diff --git a/core/lib/Drupal/Core/Entity/ContentEntityBase.php b/core/lib/Drupal/Core/Entity/ContentEntityBase.php
index 9e83814..fa78afe 100644
--- a/core/lib/Drupal/Core/Entity/ContentEntityBase.php
+++ b/core/lib/Drupal/Core/Entity/ContentEntityBase.php
@@ -340,6 +340,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.
@@ -1001,6 +1008,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 a7d1134..3eba84a 100644
--- a/core/lib/Drupal/Core/Entity/EntityType.php
+++ b/core/lib/Drupal/Core/Entity/EntityType.php
@@ -269,6 +269,7 @@ public function __construct($definition) {
     // Ensure defaults.
     $this->entity_keys += array(
       'revision' => '',
+      'revision_uuid' => '',
       'bundle' => '',
       'langcode' => '',
       'default_langcode' => 'default_langcode',
diff --git a/core/lib/Drupal/Core/Entity/EntityTypeInterface.php b/core/lib/Drupal/Core/Entity/EntityTypeInterface.php
index 1120eff..32efa95 100644
--- a/core/lib/Drupal/Core/Entity/EntityTypeInterface.php
+++ b/core/lib/Drupal/Core/Entity/EntityTypeInterface.php
@@ -93,6 +93,10 @@ 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.
+   *     @todo Should the revision_uuid key be populated by default 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 f9433bc..e120c96 100644
--- a/core/lib/Drupal/Core/Entity/RevisionableInterface.php
+++ b/core/lib/Drupal/Core/Entity/RevisionableInterface.php
@@ -45,6 +45,15 @@ public function setNewRevision($value = TRUE);
   public function getRevisionId();
 
   /**
+   * Gets the revision universally-unique identifier of the entity.
+   *
+   * @return string
+   *   The revision UUID of the entity, or NULL if the entity does not
+   *   have a revision UUID.
+   */
+  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 2b4f9a4..bae4165 100644
--- a/core/lib/Drupal/Core/Entity/Sql/SqlContentEntityStorage.php
+++ b/core/lib/Drupal/Core/Entity/Sql/SqlContentEntityStorage.php
@@ -7,6 +7,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;
@@ -60,6 +61,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
@@ -131,7 +141,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')
     );
   }
 
@@ -159,11 +170,14 @@ 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_service
+   *   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_service) {
     parent::__construct($entity_type, $entity_manager, $cache);
     $this->database = $database;
     $this->languageManager = $language_manager;
+    $this->uuidService = $uuid_service;
     $this->initTableLayout();
   }
 
@@ -175,6 +189,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;
@@ -185,6 +200,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();
@@ -291,7 +307,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($definitions);
       $revisionable_fields = array_keys(array_filter($definitions, function (FieldStorageDefinitionInterface $definition) {
         return $definition->isRevisionable();
@@ -348,10 +364,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);
@@ -1023,6 +1039,18 @@ protected function saveRevision(ContentEntityInterface $entity) {
     $entity->preSaveRevision($this, $record);
 
     if ($entity->isNewRevision()) {
+      // Generating a new revision should generate a new revision UUID. There
+      // are cases where external sources may preset the revision UUID, so we
+      // need to allow for that here.
+      if ($this->revisionUuidKey) {
+        if (isset($entity->original) && $entity->original->{$this->revisionUuidKey} != $entity->original->{$this->revisionUuidKey}) {
+          $record->{$this->revisionUuidKey} = $entity->original->{$this->revisionUuidKey}->value;
+        }
+        else {
+          $record->{$this->revisionUuidKey} = $this->uuidService->generate();
+        }
+      }
+
       $insert_id = $this->database
         ->insert($this->revisionTable, array('return' => Database::RETURN_INSERT_ID))
         ->fields((array) $record)
@@ -1034,7 +1062,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();
       }
@@ -1047,8 +1078,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/modules/block_content/src/Entity/BlockContent.php b/core/modules/block_content/src/Entity/BlockContent.php
index 2a05202..8de8511 100644
--- a/core/modules/block_content/src/Entity/BlockContent.php
+++ b/core/modules/block_content/src/Entity/BlockContent.php
@@ -52,7 +52,8 @@
  *     "bundle" = "type",
  *     "label" = "info",
  *     "langcode" = "langcode",
- *     "uuid" = "uuid"
+ *     "uuid" = "uuid",
+ *     "revision_uuid" = "revision_uuid"
  *   },
  *   bundle_entity_type = "block_content_type",
  *   field_ui_base_route = "entity.block_content_type.edit_form",
@@ -166,6 +167,11 @@ public static function baseFieldDefinitions(EntityTypeInterface $entity_type) {
       ->setReadOnly(TRUE)
       ->setSetting('unsigned', TRUE);
 
+    $fields['revision_uuid'] = BaseFieldDefinition::create('uuid')
+      ->setLabel(t('UUID'))
+      ->setDescription(t('The revision UUID.'))
+      ->setReadOnly(TRUE);
+
     $fields['langcode'] = BaseFieldDefinition::create('language')
       ->setLabel(t('Language'))
       ->setDescription(t('The custom block language code.'))
diff --git a/core/modules/comment/src/CommentStorage.php b/core/modules/comment/src/CommentStorage.php
index 5ed080f..c603c87 100644
--- a/core/modules/comment/src/CommentStorage.php
+++ b/core/modules/comment/src/CommentStorage.php
@@ -7,6 +7,7 @@
 
 namespace Drupal\comment;
 
+use Drupal\Component\Uuid\UuidInterface;
 use Drupal\Core\Cache\CacheBackendInterface;
 use Drupal\Core\Database\Connection;
 use Drupal\Core\Entity\EntityManagerInterface;
@@ -48,9 +49,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;
   }
 
@@ -64,7 +67,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/node/src/Entity/Node.php b/core/modules/node/src/Entity/Node.php
index 7b20a3b..ddac388 100644
--- a/core/modules/node/src/Entity/Node.php
+++ b/core/modules/node/src/Entity/Node.php
@@ -53,6 +53,7 @@
  *     "label" = "title",
  *     "langcode" = "langcode",
  *     "uuid" = "uuid",
+ *     "revision_uuid" = "revision_uuid",
  *     "status" = "status",
  *     "uid" = "uid",
  *   },
