diff --git a/core/lib/Drupal/Core/Database/Driver/sqlite/Connection.php b/core/lib/Drupal/Core/Database/Driver/sqlite/Connection.php
index 23dd261..f840359 100644
--- a/core/lib/Drupal/Core/Database/Driver/sqlite/Connection.php
+++ b/core/lib/Drupal/Core/Database/Driver/sqlite/Connection.php
@@ -114,6 +114,7 @@ public static function open(array &$connection_options = array()) {
     $pdo->sqliteCreateFunction('substring_index', array(__CLASS__, 'sqlFunctionSubstringIndex'), 3);
     $pdo->sqliteCreateFunction('rand', array(__CLASS__, 'sqlFunctionRand'));
     $pdo->sqliteCreateFunction('regexp', array(__CLASS__, 'sqlFunctionRegexp'));
+    $pdo->sqliteCreateFunction('UUID', array(__CLASS__, 'sqlFunctionUUID'));
 
     // SQLite does not support the LIKE BINARY operator, so we overload the
     // non-standard GLOB operator for case-sensitive matching. Another option
@@ -142,7 +143,6 @@ public static function open(array &$connection_options = array()) {
     return $pdo;
   }
 
-
   /**
    * Destructor for the SQLite connection.
    *
@@ -306,6 +306,17 @@ public static function sqlFunctionLikeBinary($pattern, $subject) {
   }
 
   /**
+   * SQLite compatibility implementation for the UUID() SQL function.
+   *
+   * @return string
+   *   A UUID string.
+   */
+  public static function sqlFunctionUUID() {
+    $generator = new \Drupal\Component\Uuid\Php();
+    return $generator->generate();
+  }
+
+  /**
    * {@inheritdoc}
    */
   public function prepare($statement, array $driver_options = array()) {
diff --git a/core/lib/Drupal/Core/Database/Schema.php b/core/lib/Drupal/Core/Database/Schema.php
index 8b9eb7e..c4bba41 100644
--- a/core/lib/Drupal/Core/Database/Schema.php
+++ b/core/lib/Drupal/Core/Database/Schema.php
@@ -305,7 +305,7 @@ public function fieldExists($table, $column) {
    *   created field will be set to the value of the key in all rows.
    *   This is most useful for creating NOT NULL columns with no default
    *   value in existing tables.
-   *   Alternatively, the 'initial_form_field' key may be used, which will
+   *   Alternatively, the 'initial_from_field' key may be used, which will
    *   auto-populate the new field with values from the specified field.
    * @param $keys_new
    *   (optional) Keys and indexes specification to be created on the
diff --git a/core/lib/Drupal/Core/Entity/ContentEntityBase.php b/core/lib/Drupal/Core/Entity/ContentEntityBase.php
index 7c0a458..3532937 100644
--- a/core/lib/Drupal/Core/Entity/ContentEntityBase.php
+++ b/core/lib/Drupal/Core/Entity/ContentEntityBase.php
@@ -335,6 +335,13 @@ public function getRevisionId() {
   /**
    * {@inheritdoc}
    */
+  public function getRevisionUuid() {
+    return $this->getEntityKey('revision_uuid');
+  }
+
+  /**
+   * {@inheritdoc}
+   */
   public function isTranslatable() {
     // Check that the bundle is translatable, the entity has a language defined
     // and if we have more than one language on the site.
@@ -996,6 +1003,12 @@ public function createDuplicate() {
     // Check whether the entity type supports revisions and initialize it if so.
     if ($entity_type->isRevisionable()) {
       $duplicate->{$entity_type->getKey('revision')}->value = NULL;
+
+      // Check if the entity type supports revision UUIDs and generate a new one
+      // if so.
+      if ($entity_type->hasKey('revision_uuid')) {
+        $duplicate->{$entity_type->getKey('revision_uuid')}->value = $this->uuidGenerator()->generate();
+      }
     }
 
     return $duplicate;
@@ -1138,6 +1151,11 @@ public static function baseFieldDefinitions(EntityTypeInterface $entity_type) {
         ->setReadOnly(TRUE)
         ->setSetting('unsigned', TRUE);
     }
+    if ($entity_type->hasKey('revision_uuid')) {
+      $fields[$entity_type->getKey('revision_uuid')] = BaseFieldDefinition::create('uuid')
+        ->setLabel(new TranslatableMarkup('Revision UUID'))
+        ->setReadOnly(TRUE);
+    }
     if ($entity_type->hasKey('langcode')) {
       $fields[$entity_type->getKey('langcode')] = BaseFieldDefinition::create('language')
         ->setLabel(new TranslatableMarkup('Language'))
diff --git a/core/lib/Drupal/Core/Entity/EntityType.php b/core/lib/Drupal/Core/Entity/EntityType.php
index 89b83cf..2b41636 100644
--- a/core/lib/Drupal/Core/Entity/EntityType.php
+++ b/core/lib/Drupal/Core/Entity/EntityType.php
@@ -288,10 +288,18 @@ public function __construct($definition) {
     // Ensure defaults.
     $this->entity_keys += array(
       'revision' => '',
+      'revision_uuid' => '',
       'bundle' => '',
       'langcode' => '',
       'default_langcode' => 'default_langcode',
     );
+
+    // If the entity type is revisionable, provide a default value for the
+    // 'revision_uuid' key.
+    if (!empty($this->entity_keys['revision']) && empty($this->entity_keys['revision_uuid'])) {
+      $this->entity_keys['revision_uuid'] = 'revision_uuid';
+    }
+
     $this->handlers += array(
       'access' => 'Drupal\Core\Entity\EntityAccessControlHandler',
     );
diff --git a/core/lib/Drupal/Core/Entity/EntityTypeInterface.php b/core/lib/Drupal/Core/Entity/EntityTypeInterface.php
index 398347f..1a67f9b 100644
--- a/core/lib/Drupal/Core/Entity/EntityTypeInterface.php
+++ b/core/lib/Drupal/Core/Entity/EntityTypeInterface.php
@@ -88,6 +88,9 @@ public function getOriginalClass();
    *     revision ID of the entity. The Field API assumes that all revision IDs
    *     are unique across all entities of a type. If this entry is omitted
    *     the entities of this type are not revisionable.
+   *   - revision_uuid: (optional) The name of the property that contains the
+   *     revision UUID of the entity. Defaults to "revision_uuid" if the
+   *     'revision' key is set.
    *   - bundle: (optional) The name of the property that contains the bundle
    *     name for the entity. The bundle name defines which set of fields are
    *     attached to the entity (e.g. what nodes call "content type"). This
diff --git a/core/lib/Drupal/Core/Entity/RevisionableInterface.php b/core/lib/Drupal/Core/Entity/RevisionableInterface.php
index 14690e3..34b29e0 100644
--- a/core/lib/Drupal/Core/Entity/RevisionableInterface.php
+++ b/core/lib/Drupal/Core/Entity/RevisionableInterface.php
@@ -40,6 +40,21 @@ public function setNewRevision($value = TRUE);
   public function getRevisionId();
 
   /**
+   * Gets the revision universally-unique identifier of the entity.
+   *
+   * This identifier can be used when moving specific revisions between two
+   * systems. The UUID of the entity itself is not unique enough for the
+   * revision and the revision ID has no meaning.
+   *
+   * Note, all translations share the same revision UUID.
+   *
+   * @return string
+   *   The revision UUID of the entity, or NULL if the entity does not
+   *   support revision UUID's.
+   */
+  public function getRevisionUuid();
+
+  /**
    * Checks if this entity is the default revision.
    *
    * @param bool $new_value
diff --git a/core/lib/Drupal/Core/Entity/Sql/SqlContentEntityStorage.php b/core/lib/Drupal/Core/Entity/Sql/SqlContentEntityStorage.php
index 2ea450d..134eb5e 100644
--- a/core/lib/Drupal/Core/Entity/Sql/SqlContentEntityStorage.php
+++ b/core/lib/Drupal/Core/Entity/Sql/SqlContentEntityStorage.php
@@ -2,6 +2,7 @@
 
 namespace Drupal\Core\Entity\Sql;
 
+use Drupal\Component\Uuid\UuidInterface;
 use Drupal\Core\Cache\CacheBackendInterface;
 use Drupal\Core\Database\Connection;
 use Drupal\Core\Database\Database;
@@ -55,6 +56,15 @@ class SqlContentEntityStorage extends ContentEntityStorageBase implements SqlEnt
   protected $revisionKey = FALSE;
 
   /**
+   * Name of entity's revision UUID database field, if it supports revisions.
+   *
+   * Has the value FALSE if this entity does not use revisions.
+   *
+   * @var string
+   */
+  protected $revisionUuidKey = FALSE;
+
+  /**
    * The entity langcode key.
    *
    * @var string|bool
@@ -126,7 +136,8 @@ public static function createInstance(ContainerInterface $container, EntityTypeI
       $container->get('database'),
       $container->get('entity.manager'),
       $container->get('cache.entity'),
-      $container->get('language_manager')
+      $container->get('language_manager'),
+      $container->get('uuid')
     );
   }
 
@@ -154,11 +165,18 @@ public function getFieldStorageDefinitions() {
    *   The cache backend to be used.
    * @param \Drupal\Core\Language\LanguageManagerInterface $language_manager
    *   The language manager.
+   * @param \Drupal\Component\Uuid\UuidInterface $uuid_generator
+   *   The UUID service.
    */
-  public function __construct(EntityTypeInterface $entity_type, Connection $database, EntityManagerInterface $entity_manager, CacheBackendInterface $cache, LanguageManagerInterface $language_manager) {
+  public function __construct(EntityTypeInterface $entity_type, Connection $database, EntityManagerInterface $entity_manager, CacheBackendInterface $cache, LanguageManagerInterface $language_manager, UuidInterface $uuid_generator = NULL) {
     parent::__construct($entity_type, $entity_manager, $cache);
     $this->database = $database;
     $this->languageManager = $language_manager;
+
+    // Maintain backwards compatibility, remove in D9.
+    if (!$uuid_generator) {
+      $this->uuidService = \Drupal::service('uuid');
+    }
     $this->initTableLayout();
   }
 
@@ -170,6 +188,7 @@ protected function initTableLayout() {
     // are correctly reflected in the table layout.
     $this->tableMapping = NULL;
     $this->revisionKey = NULL;
+    $this->revisionUuidKey = NULL;
     $this->revisionTable = NULL;
     $this->dataTable = NULL;
     $this->revisionDataTable = NULL;
@@ -180,6 +199,7 @@ protected function initTableLayout() {
     $revisionable = $this->entityType->isRevisionable();
     if ($revisionable) {
       $this->revisionKey = $this->entityType->getKey('revision') ?: 'revision_id';
+      $this->revisionUuidKey = $this->entityType->getKey('revision_uuid') ?: 'revision_uuid';
       $this->revisionTable = $this->entityType->getRevisionTable() ?: $this->entityTypeId . '_revision';
     }
     $translatable = $this->entityType->isTranslatable();
@@ -286,7 +306,7 @@ public function getTableMapping(array $storage_definitions = NULL) {
         return $table_mapping->allowsSharedTableStorage($definition);
       });
 
-      $key_fields = array_values(array_filter(array($this->idKey, $this->revisionKey, $this->bundleKey, $this->uuidKey, $this->langcodeKey)));
+      $key_fields = array_values(array_filter(array($this->idKey, $this->revisionKey, $this->bundleKey, $this->uuidKey, $this->revisionUuidKey, $this->langcodeKey)));
       $all_fields = array_keys($shared_table_definitions);
       $revisionable_fields = array_keys(array_filter($shared_table_definitions, function (FieldStorageDefinitionInterface $definition) {
         return $definition->isRevisionable();
@@ -316,7 +336,7 @@ public function getTableMapping(array $storage_definitions = NULL) {
         // denormalized in the base table but also stored in the revision table
         // together with the entity ID and the revision ID as identifiers.
         $table_mapping->setFieldNames($this->baseTable, array_diff($all_fields, $revision_metadata_fields));
-        $revision_key_fields = array($this->idKey, $this->revisionKey);
+        $revision_key_fields = array($this->idKey, $this->revisionKey, $this->revisionUuidKey);
         $table_mapping->setFieldNames($this->revisionTable, array_merge($revision_key_fields, $revisionable_fields));
       }
       elseif (!$revisionable && $translatable) {
@@ -343,10 +363,10 @@ public function getTableMapping(array $storage_definitions = NULL) {
         // Like in the multilingual, non-revisionable case the UUID is not
         // in the data table. Additionally, do not store revision metadata
         // fields in the data table.
-        $data_fields = array_values(array_diff($all_fields, array($this->uuidKey), $revision_metadata_fields));
+        $data_fields = array_values(array_diff($all_fields, array($this->uuidKey, $this->revisionUuidKey), $revision_metadata_fields));
         $table_mapping->setFieldNames($this->dataTable, $data_fields);
 
-        $revision_base_fields = array_merge(array($this->idKey, $this->revisionKey, $this->langcodeKey), $revision_metadata_fields);
+        $revision_base_fields = array_merge(array($this->idKey, $this->revisionKey, $this->revisionUuidKey, $this->langcodeKey), $revision_metadata_fields);
         $table_mapping->setFieldNames($this->revisionTable, $revision_base_fields);
 
         $revision_data_key_fields = array($this->idKey, $this->revisionKey, $this->langcodeKey);
@@ -1036,6 +1056,12 @@ protected function saveRevision(ContentEntityInterface $entity) {
     $entity->preSaveRevision($this, $record);
 
     if ($entity->isNewRevision()) {
+      // Generating a new revision should generate a new revision UUID.
+      $generate_uuid = $this->revisionUuidKey && ((!$entity->original) || $entity->original->getRevisionUuid() === $record->revision_uuid);
+      if ($generate_uuid) {
+        $record->{$this->revisionUuidKey} = $this->uuidService->generate();
+      }
+
       $insert_id = $this->database
         ->insert($this->revisionTable, array('return' => Database::RETURN_INSERT_ID))
         ->fields((array) $record)
@@ -1047,7 +1073,10 @@ protected function saveRevision(ContentEntityInterface $entity) {
       }
       if ($entity->isDefaultRevision()) {
         $this->database->update($this->entityType->getBaseTable())
-          ->fields(array($this->revisionKey => $record->{$this->revisionKey}))
+          ->fields([
+            $this->revisionKey => $record->{$this->revisionKey},
+            $this->revisionUuidKey => $record->{$this->revisionUuidKey},
+          ])
           ->condition($this->idKey, $record->{$this->idKey})
           ->execute();
       }
@@ -1060,8 +1089,11 @@ protected function saveRevision(ContentEntityInterface $entity) {
         ->execute();
     }
 
-    // Make sure to update the new revision key for the entity.
+    // Make sure to update the new revision ID and UUID keys for the entity.
     $entity->{$this->revisionKey}->value = $record->{$this->revisionKey};
+    if ($this->revisionUuidKey) {
+      $entity->{$this->revisionUuidKey}->value = $record->{$this->revisionUuidKey};
+    }
 
     return $record->{$this->revisionKey};
   }
diff --git a/core/lib/Drupal/Core/Entity/Sql/SqlContentEntityStorageSchema.php b/core/lib/Drupal/Core/Entity/Sql/SqlContentEntityStorageSchema.php
index 0d64e31..a0fe9f2 100644
--- a/core/lib/Drupal/Core/Entity/Sql/SqlContentEntityStorageSchema.php
+++ b/core/lib/Drupal/Core/Entity/Sql/SqlContentEntityStorageSchema.php
@@ -176,7 +176,6 @@ public function requiresFieldStorageSchemaChanges(FieldStorageDefinitionInterfac
 
     if (
       $storage_definition->hasCustomStorage() != $original->hasCustomStorage() ||
-      $storage_definition->getSchema() != $original->getSchema() ||
       $storage_definition->isRevisionable() != $original->isRevisionable() ||
       $table_mapping->allowsSharedTableStorage($storage_definition) != $table_mapping->allowsSharedTableStorage($original) ||
       $table_mapping->requiresDedicatedTableStorage($storage_definition) != $table_mapping->requiresDedicatedTableStorage($original)
@@ -192,7 +191,40 @@ public function requiresFieldStorageSchemaChanges(FieldStorageDefinitionInterfac
       return FALSE;
     }
 
-    return $this->getSchemaFromStorageDefinition($storage_definition) != $this->loadFieldSchemaData($original);
+    $storage_definition_schema = $this->getSchemaFromStorageDefinition($storage_definition);
+    $original_schema = $this->loadFieldSchemaData($original);
+
+    // Filter out irrelevant schema.
+    return $this->removeIrrelevantSchemaKeys($storage_definition_schema) != $this->removeIrrelevantSchemaKeys($original_schema);
+  }
+
+  /**
+   * Remove irrelevant schema keys.
+   *
+   * We need to remove irrelevant schema keys before comparing two schemas to
+   * see if they've changed as there are certain keys that can safely be added
+   * at any point to existing schema. E.g. initial or initial_from_field.
+   *
+   * @param array $schema
+   *   The schema array.
+   * @param array $remove_keys
+   *   (optional) An array of keys to remove regardless of the depth.
+   *
+   * @return array
+   *   The schema with any irrelevant keys removed.
+   */
+  protected function removeIrrelevantSchemaKeys(&$schema, $remove_keys = ['initial', 'initial_from_field']) {
+    foreach ($schema as $key => &$value) {
+      if (is_array($value)) {
+        $this->removeIrrelevantSchemaKeys($value, $remove_keys);
+      }
+      else {
+        if (in_array($key, $remove_keys, TRUE)) {
+          unset($schema[$key]);
+        }
+      }
+    }
+    return $schema;
   }
 
   /**
@@ -1153,7 +1185,9 @@ protected function createSharedTableSchema(FieldStorageDefinitionInterface $stor
             }
             if (!empty($schema[$table_name]['unique keys'])) {
               foreach ($schema[$table_name]['unique keys'] as $name => $specifier) {
-                $schema_handler->addUniqueKey($table_name, $name, $specifier);
+                // Check if the unique key exists because it might already have
+                // been created as part of the earlier entity type update event.
+                $this->addUniqueKey($table_name, $name, $specifier);
               }
             }
           }
@@ -1944,7 +1978,19 @@ protected function isTableEmpty($table_name) {
    *   Returns TRUE if there are schema changes in the column definitions.
    */
   protected function hasColumnChanges(FieldStorageDefinitionInterface $storage_definition, FieldStorageDefinitionInterface $original) {
-    if ($storage_definition->getColumns() != $original->getColumns()) {
+    // Remove any fields that can be changed in the column array structure such
+    // as initial.
+    $new_columns = $storage_definition->getColumns();
+    $original_columns = $original->getColumns();
+    foreach ($new_columns as $delta => $column) {
+      foreach ($column as $key => $value) {
+        if (in_array($key, ['initial', 'initial_from_field'], TRUE)) {
+          unset($new_columns[$delta][$key]);
+          unset($original_columns[$delta][$key]);
+        }
+      }
+    }
+    if ($new_columns != $original_columns) {
       // Base field definitions have schema data stored in the original
       // definition.
       return TRUE;
diff --git a/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/UuidItem.php b/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/UuidItem.php
index 94aa8aa..b7daa16 100644
--- a/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/UuidItem.php
+++ b/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/UuidItem.php
@@ -45,6 +45,7 @@ public function applyDefaultValue($notify = TRUE) {
   public static function schema(FieldStorageDefinitionInterface $field_definition) {
     $schema = parent::schema($field_definition);
     $schema['unique keys']['value'] = array('value');
+    $schema['columns']['value']['initial_from_field'] = 'UUID()';
     return $schema;
   }
 
diff --git a/core/modules/block_content/src/Entity/BlockContent.php b/core/modules/block_content/src/Entity/BlockContent.php
index 13af342..ec8b50e 100644
--- a/core/modules/block_content/src/Entity/BlockContent.php
+++ b/core/modules/block_content/src/Entity/BlockContent.php
@@ -166,6 +166,11 @@ public static function baseFieldDefinitions(EntityTypeInterface $entity_type) {
     $fields['type']->setLabel(t('Block type'))
       ->setDescription(t('The block type.'));
 
+    $fields['revision_uuid'] = BaseFieldDefinition::create('uuid')
+      ->setLabel(t('Revision UUID'))
+      ->setDescription(t('The revision UUID.'))
+      ->setReadOnly(TRUE);
+
     $fields['info'] = BaseFieldDefinition::create('string')
       ->setLabel(t('Block description'))
       ->setDescription(t('A brief description of your block.'))
diff --git a/core/modules/comment/src/CommentStorage.php b/core/modules/comment/src/CommentStorage.php
index cc4fdcf..0931f41 100644
--- a/core/modules/comment/src/CommentStorage.php
+++ b/core/modules/comment/src/CommentStorage.php
@@ -2,6 +2,7 @@
 
 namespace Drupal\comment;
 
+use Drupal\Component\Uuid\UuidInterface;
 use Drupal\Core\Cache\CacheBackendInterface;
 use Drupal\Core\Database\Connection;
 use Drupal\Core\Entity\EntityManagerInterface;
@@ -43,9 +44,11 @@ class CommentStorage extends SqlContentEntityStorage implements CommentStorageIn
    *   Cache backend instance to use.
    * @param \Drupal\Core\Language\LanguageManagerInterface $language_manager
    *   The language manager.
+   * @param \Drupal\Component\Uuid\UuidInterface $uuid_service
+   *   The UUID service.
    */
-  public function __construct(EntityTypeInterface $entity_info, Connection $database, EntityManagerInterface $entity_manager, AccountInterface $current_user, CacheBackendInterface $cache, LanguageManagerInterface $language_manager) {
-    parent::__construct($entity_info, $database, $entity_manager, $cache, $language_manager);
+  public function __construct(EntityTypeInterface $entity_info, Connection $database, EntityManagerInterface $entity_manager, AccountInterface $current_user, CacheBackendInterface $cache, LanguageManagerInterface $language_manager, UuidInterface $uuid_service) {
+    parent::__construct($entity_info, $database, $entity_manager, $cache, $language_manager, $uuid_service);
     $this->currentUser = $current_user;
   }
 
@@ -59,7 +62,8 @@ public static function createInstance(ContainerInterface $container, EntityTypeI
       $container->get('entity.manager'),
       $container->get('current_user'),
       $container->get('cache.entity'),
-      $container->get('language_manager')
+      $container->get('language_manager'),
+      $container->get('uuid')
     );
   }
 
diff --git a/core/modules/serialization/src/Tests/EntitySerializationTest.php b/core/modules/serialization/src/Tests/EntitySerializationTest.php
index 00ea14f..c9e288c 100644
--- a/core/modules/serialization/src/Tests/EntitySerializationTest.php
+++ b/core/modules/serialization/src/Tests/EntitySerializationTest.php
@@ -119,6 +119,9 @@ public function testNormalize() {
       'revision_id' => array(
         array('value' => 1),
       ),
+      'revision_uuid' => array(
+        array('value' => $this->entity->getRevisionUuid()),
+      ),
       'default_langcode' => array(
         array('value' => TRUE),
       ),
@@ -190,6 +193,7 @@ public function testSerialize() {
       'created' => '<created><value>' . $this->entity->created->value . '</value></created>',
       'user_id' => '<user_id><target_id>' . $this->user->id() . '</target_id><target_type>' . $this->user->getEntityTypeId() . '</target_type><target_uuid>' . $this->user->uuid() . '</target_uuid><url>' . $this->user->url() . '</url></user_id>',
       'revision_id' => '<revision_id><value>' . $this->entity->getRevisionId() . '</value></revision_id>',
+      'revision_uuid' => '<revision_uuid><value>' . $this->entity->getRevisionUuid() . '</value></revision_uuid>',
       'default_langcode' => '<default_langcode><value>1</value></default_langcode>',
       'non_rev_field' => '<non_rev_field/>',
       'field_test_text' => '<field_test_text><value>' . $this->values['field_test_text']['value'] . '</value><format>' . $this->values['field_test_text']['format'] . '</format></field_test_text>',
diff --git a/core/modules/system/src/Tests/Entity/EntityDefinitionTestTrait.php b/core/modules/system/src/Tests/Entity/EntityDefinitionTestTrait.php
index 0123597..0dc7053 100644
--- a/core/modules/system/src/Tests/Entity/EntityDefinitionTestTrait.php
+++ b/core/modules/system/src/Tests/Entity/EntityDefinitionTestTrait.php
@@ -36,6 +36,7 @@ protected function updateEntityTypeToRevisionable() {
 
     $keys = $entity_type->getKeys();
     $keys['revision'] = 'revision_id';
+    $keys['revision_uuid'] = 'revision_uuid';
     $entity_type->set('entity_keys', $keys);
 
     $this->state->set('entity_test_update.entity_type', $entity_type);
diff --git a/core/modules/system/system.install b/core/modules/system/system.install
index 154a55b..3535d5e 100644
--- a/core/modules/system/system.install
+++ b/core/modules/system/system.install
@@ -1680,3 +1680,25 @@ function system_update_8200(&$sandbox) {
   $sandbox['config_names'] = array_diff($sandbox['config_names'], $config_names_to_process);
   $sandbox['#finished'] = empty($sandbox['config_names']) ? 1 : ($sandbox['max'] - count($sandbox['config_names'])) / $sandbox['max'];
 }
+
+/**
+ * Install new revision_uuid schema.
+ */
+function system_update_8300() {
+  foreach (\Drupal::entityTypeManager()->getDefinitions() as $entity_type_id => $entity_type) {
+    /** @var \Drupal\Core\Entity\EntityDefinitionUpdateManagerInterface $manager */
+    $manager = \Drupal::entityDefinitionUpdateManager();
+
+    // Install the new revision_uuid field.
+    if ($entity_type->hasKey('revision_uuid')) {
+      $field_manager = \Drupal::service('entity_field.manager');
+      $field_storage_definitions = $field_manager->getFieldStorageDefinitions($entity_type_id);
+      $manager->installFieldStorageDefinition($entity_type->getKey('revision_uuid'), $entity_type_id, $entity_type->getProvider(), $field_storage_definitions[$entity_type->getKey('revision_uuid')]);
+    }
+
+    // Update the existing uuid field which has a new schema.
+    if ($entity_type->hasKey('uuid') && $definition = $manager->getFieldStorageDefinition('uuid', $entity_type_id)) {
+      $manager->updateFieldStorageDefinition($definition);
+    }
+  }
+}
diff --git a/core/modules/system/tests/modules/entity_schema_test/entity_schema_test.module b/core/modules/system/tests/modules/entity_schema_test/entity_schema_test.module
index 45892a8..ecd9da6 100644
--- a/core/modules/system/tests/modules/entity_schema_test/entity_schema_test.module
+++ b/core/modules/system/tests/modules/entity_schema_test/entity_schema_test.module
@@ -20,6 +20,7 @@ function entity_schema_test_entity_type_alter(array &$entity_types) {
     $entity_type->set('data_table', 'entity_test_field_data');
     $keys = $entity_type->getKeys();
     $keys['revision'] = 'revision_id';
+    $keys['revision_uuid'] = 'revision_uuid';
     $entity_type->set('entity_keys', $keys);
   }
 }
diff --git a/core/tests/Drupal/KernelTests/Core/Entity/EntityDefinitionUpdateTest.php b/core/tests/Drupal/KernelTests/Core/Entity/EntityDefinitionUpdateTest.php
index 23cf034..8b6b7e4 100644
--- a/core/tests/Drupal/KernelTests/Core/Entity/EntityDefinitionUpdateTest.php
+++ b/core/tests/Drupal/KernelTests/Core/Entity/EntityDefinitionUpdateTest.php
@@ -102,6 +102,7 @@ public function testEntityTypeUpdateWithoutData() {
     $expected = array(
       'entity_test_update' => array(
         t('The %entity_type entity type needs to be updated.', ['%entity_type' => $this->entityManager->getDefinition('entity_test_update')->getLabel()]),
+        t('The %field_name field needs to be installed.', ['%field_name' => $this->entityManager->getFieldStorageDefinitions('entity_test_update')['revision_uuid']->getLabel()]),
       ),
     );
     $this->assertEqual($this->entityDefinitionUpdateManager->getChangeSummary(), $expected); //, 'EntityDefinitionUpdateManager reports the expected change summary.');
diff --git a/core/tests/Drupal/KernelTests/Core/Entity/EntityFieldTest.php b/core/tests/Drupal/KernelTests/Core/Entity/EntityFieldTest.php
index 56af888..e51b132 100644
--- a/core/tests/Drupal/KernelTests/Core/Entity/EntityFieldTest.php
+++ b/core/tests/Drupal/KernelTests/Core/Entity/EntityFieldTest.php
@@ -572,6 +572,9 @@ protected function doTestDataStructureInterfaces($entity_type) {
       // Field format.
       NULL,
     );
+    if ($uuid = $entity->getRevisionUuid()) {
+      $target_strings[] = $uuid;
+    }
     asort($strings);
     asort($target_strings);
     $this->assertEqual(array_values($strings), array_values($target_strings), format_string('%entity_type: All contained strings found.', array('%entity_type' => $entity_type)));
diff --git a/core/tests/Drupal/KernelTests/Core/Entity/EntityUUIDTest.php b/core/tests/Drupal/KernelTests/Core/Entity/EntityUUIDTest.php
index ae26ec5..2541264 100644
--- a/core/tests/Drupal/KernelTests/Core/Entity/EntityUUIDTest.php
+++ b/core/tests/Drupal/KernelTests/Core/Entity/EntityUUIDTest.php
@@ -97,6 +97,10 @@ protected function assertCRUD($entity_type) {
           $this->assertNotEqual($entity_duplicate->getRevisionId(), $entity->getRevisionId());
           $this->assertNotEqual($entity_duplicate->{$property}->getValue(), $entity->{$property}->getValue());
           break;
+        case 'revision_uuid':
+          $this->assertNotNull($entity->getRevisionUuid());
+          $this->assertNotEqual($entity_duplicate->getRevisionUuid(), $entity->getRevisionUuid());
+          break;
         default:
           $this->assertEqual($entity_duplicate->{$property}->getValue(), $entity->{$property}->getValue());
       }
diff --git a/core/tests/Drupal/Tests/Core/Entity/EntityTypeTest.php b/core/tests/Drupal/Tests/Core/Entity/EntityTypeTest.php
index d633afc..7f2f67a 100644
--- a/core/tests/Drupal/Tests/Core/Entity/EntityTypeTest.php
+++ b/core/tests/Drupal/Tests/Core/Entity/EntityTypeTest.php
@@ -117,9 +117,9 @@ public function providerTestSet() {
    */
   public function providerTestGetKeys() {
     return array(
-      array(array(), array('revision' => '', 'bundle' => '', 'langcode' => '')),
-      array(array('id' => 'id'), array('id' => 'id', 'revision' => '', 'bundle' => '', 'langcode' => '')),
-      array(array('bundle' => 'bundle'), array('bundle' => 'bundle', 'revision' => '', 'langcode' => '')),
+      array(array(), array('revision' => '', 'revision_uuid' => '', 'bundle' => '', 'langcode' => '')),
+      array(array('id' => 'id'), array('id' => 'id', 'revision' => '', 'revision_uuid' => '', 'bundle' => '', 'langcode' => '')),
+      array(array('bundle' => 'bundle'), array('bundle' => 'bundle', 'revision' => '', 'revision_uuid' => '', 'langcode' => '')),
     );
   }
 
diff --git a/core/tests/Drupal/Tests/Core/Entity/Sql/SqlContentEntityStorageTest.php b/core/tests/Drupal/Tests/Core/Entity/Sql/SqlContentEntityStorageTest.php
index 56b4b00..cb3c897 100644
--- a/core/tests/Drupal/Tests/Core/Entity/Sql/SqlContentEntityStorageTest.php
+++ b/core/tests/Drupal/Tests/Core/Entity/Sql/SqlContentEntityStorageTest.php
@@ -92,6 +92,13 @@ class SqlContentEntityStorageTest extends UnitTestCase {
   protected $connection;
 
   /**
+   * The UUID service.
+   *
+   * @var \Drupal\Component\Uuid\UuidInterface
+   */
+  protected $uuidGenerator;
+
+  /**
    * {@inheritdoc}
    */
   protected function setUp() {
@@ -113,6 +120,7 @@ protected function setUp() {
     $this->connection = $this->getMockBuilder('Drupal\Core\Database\Connection')
       ->disableOriginalConstructor()
       ->getMock();
+    $this->uuidGenerator = $this->getMock('Drupal\Component\Uuid\UuidInterface');
   }
 
   /**
@@ -342,7 +350,7 @@ public function testOnEntityTypeCreate() {
       ->will($this->returnValue($schema_handler));
 
     $storage = $this->getMockBuilder('Drupal\Core\Entity\Sql\SqlContentEntityStorage')
-      ->setConstructorArgs(array($this->entityType, $this->connection, $this->entityManager, $this->cache, $this->languageManager))
+      ->setConstructorArgs(array($this->entityType, $this->connection, $this->entityManager, $this->cache, $this->languageManager, $this->uuidGenerator))
       ->setMethods(array('getStorageSchema'))
       ->getMock();
 
@@ -520,6 +528,7 @@ public function testGetTableMappingRevisionable(array $entity_keys) {
       'revision' => 'test_revision',
       'bundle' => $entity_keys['bundle'],
       'uuid' => $entity_keys['uuid'],
+      'revision_uuid' => 'test_revision_uuid',
     );
 
     $this->entityType->expects($this->exactly(2))
@@ -532,6 +541,7 @@ public function testGetTableMappingRevisionable(array $entity_keys) {
         array('uuid', $entity_keys['uuid']),
         array('bundle', $entity_keys['bundle']),
         array('revision', $entity_keys['revision']),
+        array('revision_uuid', $entity_keys['revision_uuid']),
       )));
 
     $this->setUpEntityStorage();
@@ -543,7 +553,7 @@ public function testGetTableMappingRevisionable(array $entity_keys) {
 
     $expected = array_values(array_filter($entity_keys));
     $this->assertEquals($expected, $mapping->getFieldNames('entity_test'));
-    $expected = array($entity_keys['id'], $entity_keys['revision']);
+    $expected = array($entity_keys['id'], $entity_keys['revision'], $entity_keys['revision_uuid']);
     $this->assertEquals($expected, $mapping->getFieldNames('entity_test_revision'));
 
     $this->assertEquals(array(), $mapping->getExtraColumns('entity_test'));
@@ -568,6 +578,7 @@ public function testGetTableMappingRevisionableWithFields(array $entity_keys) {
       'revision' => 'test_revision',
       'bundle' => $entity_keys['bundle'],
       'uuid' => $entity_keys['uuid'],
+      'revision_uuid' => 'test_revision_uuid',
     );
 
     // PHPUnit does not allow for multiple data providers.
@@ -602,6 +613,7 @@ public function testGetTableMappingRevisionableWithFields(array $entity_keys) {
           array('uuid', $entity_keys['uuid']),
           array('bundle', $entity_keys['bundle']),
           array('revision', $entity_keys['revision']),
+          array('revision_uuid', $entity_keys['revision_uuid']),
         )));
 
       $this->setUpEntityStorage();
@@ -613,7 +625,7 @@ public function testGetTableMappingRevisionableWithFields(array $entity_keys) {
 
       $this->assertEquals($field_names, $mapping->getFieldNames('entity_test'));
       $expected = array_merge(
-        array($entity_keys['id'], $entity_keys['revision']),
+        array($entity_keys['id'], $entity_keys['revision'], $entity_keys['revision_uuid']),
         $revisionable_field_names,
         $revision_metadata_field_names
       );
@@ -756,6 +768,7 @@ public function testGetTableMappingRevisionableTranslatable(array $entity_keys)
     $entity_keys = array(
       'id' => $entity_keys['id'],
       'revision' => 'test_revision',
+      'revision_uuid' => 'test_revision_uuid',
       'bundle' => $entity_keys['bundle'],
       'uuid' => $entity_keys['uuid'],
       'langcode' => 'langcode',
@@ -777,6 +790,7 @@ public function testGetTableMappingRevisionableTranslatable(array $entity_keys)
         array('uuid', $entity_keys['uuid']),
         array('bundle', $entity_keys['bundle']),
         array('revision', $entity_keys['revision']),
+        array('revision_uuid', $entity_keys['revision_uuid']),
         array('langcode', $entity_keys['langcode']),
       )));
 
@@ -798,6 +812,7 @@ public function testGetTableMappingRevisionableTranslatable(array $entity_keys)
       $entity_keys['revision'],
       $entity_keys['bundle'],
       $entity_keys['uuid'],
+      $entity_keys['revision_uuid'],
       $entity_keys['langcode'],
     )));
     $actual = $mapping->getFieldNames('entity_test');
@@ -807,6 +822,7 @@ public function testGetTableMappingRevisionableTranslatable(array $entity_keys)
     $expected = array_values(array_filter(array(
       $entity_keys['id'],
       $entity_keys['revision'],
+      $entity_keys['revision_uuid'],
       $entity_keys['langcode'],
     )));
     $actual = $mapping->getFieldNames('entity_test_revision');
@@ -856,6 +872,7 @@ public function testGetTableMappingRevisionableTranslatableWithFields(array $ent
     $entity_keys = array(
       'id' => $entity_keys['id'],
       'revision' => 'test_revision',
+      'revision_uuid' => 'test_revision_uuid',
       'bundle' => $entity_keys['bundle'],
       'uuid' => $entity_keys['uuid'],
       'langcode' => 'langcode',
@@ -898,6 +915,7 @@ public function testGetTableMappingRevisionableTranslatableWithFields(array $ent
           array('uuid', $entity_keys['uuid']),
           array('bundle', $entity_keys['bundle']),
           array('revision', $entity_keys['revision']),
+          array('revision_uuid', $entity_keys['revision_uuid']),
           array('langcode', $entity_keys['langcode']),
         )));
 
@@ -927,6 +945,7 @@ public function testGetTableMappingRevisionableTranslatableWithFields(array $ent
         $entity_keys['revision'],
         $entity_keys['bundle'],
         $entity_keys['uuid'],
+        $entity_keys['revision_uuid'],
         $entity_keys['langcode'],
       )));
       $actual = $mapping->getFieldNames('entity_test');
@@ -936,6 +955,7 @@ public function testGetTableMappingRevisionableTranslatableWithFields(array $ent
       $expected = array_merge(array_filter(array(
         $entity_keys['id'],
         $entity_keys['revision'],
+        $entity_keys['revision_uuid'],
         $entity_keys['langcode'],
       )), $revision_metadata_field_names);
       $actual = $mapping->getFieldNames('entity_test_revision');
@@ -1085,7 +1105,7 @@ protected function setUpEntityStorage() {
       ->method('getBaseFieldDefinitions')
       ->will($this->returnValue($this->fieldDefinitions));
 
-    $this->entityStorage = new SqlContentEntityStorage($this->entityType, $this->connection, $this->entityManager, $this->cache, $this->languageManager);
+    $this->entityStorage = new SqlContentEntityStorage($this->entityType, $this->connection, $this->entityManager, $this->cache, $this->languageManager, $this->uuidGenerator);
   }
 
   /**
@@ -1162,7 +1182,7 @@ public function testLoadMultipleNoPersistentCache() {
       ->method('set');
 
     $entity_storage = $this->getMockBuilder('Drupal\Core\Entity\Sql\SqlContentEntityStorage')
-      ->setConstructorArgs(array($this->entityType, $this->connection, $this->entityManager, $this->cache, $this->languageManager))
+      ->setConstructorArgs(array($this->entityType, $this->connection, $this->entityManager, $this->cache, $this->languageManager, $this->uuidGenerator))
       ->setMethods(array('getFromStorage', 'invokeStorageLoadHook'))
       ->getMock();
     $entity_storage->method('invokeStorageLoadHook')
@@ -1214,7 +1234,7 @@ public function testLoadMultiplePersistentCacheMiss() {
       ->with($key, $entity, CacheBackendInterface::CACHE_PERMANENT, array($this->entityTypeId . '_values', 'entity_field_info'));
 
     $entity_storage = $this->getMockBuilder('Drupal\Core\Entity\Sql\SqlContentEntityStorage')
-      ->setConstructorArgs(array($this->entityType, $this->connection, $this->entityManager, $this->cache, $this->languageManager))
+      ->setConstructorArgs(array($this->entityType, $this->connection, $this->entityManager, $this->cache, $this->languageManager, $this->uuidGenerator))
       ->setMethods(array('getFromStorage', 'invokeStorageLoadHook'))
       ->getMock();
     $entity_storage->method('invokeStorageLoadHook')
@@ -1271,7 +1291,7 @@ public function testHasData() {
       ->method('getBaseFieldDefinitions')
       ->will($this->returnValue($this->fieldDefinitions));
 
-    $this->entityStorage = new SqlContentEntityStorage($this->entityType, $database, $this->entityManager, $this->cache, $this->languageManager);
+    $this->entityStorage = new SqlContentEntityStorage($this->entityType, $database, $this->entityManager, $this->cache, $this->languageManager, $this->uuidGenerator);
 
     $result = $this->entityStorage->hasData();
 
