diff --git a/core/modules/comment/comment.install b/core/modules/comment/comment.install
index 9b1ab88948..c44e720821 100644
--- a/core/modules/comment/comment.install
+++ b/core/modules/comment/comment.install
@@ -7,6 +7,7 @@
 
 use Drupal\comment\Entity\Comment;
 use Drupal\Core\Entity\EntityTypeInterface;
+use Drupal\Core\Field\BaseFieldDefinition;
 use Drupal\Core\StringTranslation\PluralTranslatableMarkup;
 use Drupal\Core\StringTranslation\TranslatableMarkup;
 use Drupal\field\Entity\FieldStorageConfig;
@@ -234,3 +235,54 @@ function comment_update_8701() {
   $field_definition->setRequired(TRUE);
   $definition_update_manager->updateFieldStorageDefinition($field_definition);
 }
+
+/**
+ * Add the revisionable metadata fields to comments.
+ */
+function comment_update_8702() {
+  $definition_update_manager = \Drupal::entityDefinitionUpdateManager();
+
+  // Add the revisionable metadata fields to the comment entity type.
+  $entity_type = $definition_update_manager->getEntityType('comment');
+
+  $revision_metadata_keys = [
+    'revision_user' => 'revision_user',
+    'revision_created' => 'revision_created',
+    'revision_log_message' => 'revision_log_message'
+  ];
+  $entity_type->set('revision_metadata_keys', $revision_metadata_keys);
+
+  $definition_update_manager->updateEntityType($entity_type);
+
+  // Add the revision metadata fields.
+  $revision_created = BaseFieldDefinition::create('created')
+    ->setLabel(t('Revision create time'))
+    ->setDescription(t('The time that the current revision was created.'))
+    ->setRevisionable(TRUE)
+    ->setInitialValueFromField('created');
+  $definition_update_manager->installFieldStorageDefinition('revision_created', 'comment', 'comment', $revision_created);
+
+  $revision_user = BaseFieldDefinition::create('entity_reference')
+    ->setLabel(t('Revision user'))
+    ->setDescription(t('The user ID of the author of the current revision.'))
+    ->setSetting('target_type', 'user')
+    ->setRevisionable(TRUE)
+    ->setInitialValueFromField('uid');
+  $definition_update_manager->installFieldStorageDefinition('revision_user', 'comment', 'comment', $revision_user);
+
+  $revision_log_message = BaseFieldDefinition::create('string_long')
+    ->setLabel(t('Revision log message'))
+    ->setDescription(t('Briefly describe the changes you have made.'))
+    ->setRevisionable(TRUE)
+    ->setDefaultValue('')
+    ->setDisplayOptions('form', [
+      'type' => 'string_textarea',
+      'weight' => 25,
+      'settings' => [
+        'rows' => 4,
+      ],
+    ]);
+  $definition_update_manager->installFieldStorageDefinition('revision_log_message', 'comment', 'comment', $revision_log_message);
+
+  return t('Comments have been converted to revisionable.');
+}
diff --git a/core/modules/comment/comment.module b/core/modules/comment/comment.module
index 8a63a7eae3..5c8f7d34cb 100644
--- a/core/modules/comment/comment.module
+++ b/core/modules/comment/comment.module
@@ -12,6 +12,7 @@
 
 use Drupal\comment\CommentInterface;
 use Drupal\comment\Entity\CommentType;
+use Drupal\Core\Entity\EntityTypeInterface;
 use Drupal\Core\Entity\FieldableEntityInterface;
 use Drupal\comment\Plugin\Field\FieldType\CommentItemInterface;
 use Drupal\Core\Entity\Entity\EntityViewMode;
@@ -136,6 +137,29 @@ function comment_entity_extra_field_info() {
   return $return;
 }
 
+/**
+ * Implements hook_entity_base_field_info_alter().
+ */
+function comment_entity_base_field_info_alter(&$fields, EntityTypeInterface $entity_type) {
+  // Provide a better default value for the moderation state field if the
+  // content moderation is enabled for comments.
+  if (\Drupal::moduleHandler()->moduleExists('content_moderation') && \Drupal::service('content_moderation.moderation_information')->canModerateEntitiesOfEntityType($entity_type)) {
+    $fields['moderation_state']->setDefaultValueCallback('comment_get_default_moderation_state');
+  }
+}
+
+/**
+ * Default value callback for the 'moderation_state' base field definition.
+ *
+ * @return array
+ *   An array of default values.
+ */
+function comment_get_default_moderation_state() {
+  $default_moderation_state = \Drupal::currentUser()->hasPermission('skip comment approval') ? 'published' : 'draft';
+
+  return [$default_moderation_state];
+}
+
 /**
  * Implements hook_theme().
  */
diff --git a/core/modules/comment/comment.post_update.php b/core/modules/comment/comment.post_update.php
index 64587ae154..5d8ee19143 100644
--- a/core/modules/comment/comment.post_update.php
+++ b/core/modules/comment/comment.post_update.php
@@ -7,6 +7,7 @@
 
 use Drupal\Core\Config\FileStorage;
 use Drupal\Core\Config\InstallStorage;
+use Drupal\Core\Entity\Sql\SqlContentEntityStorageSchemaConverter;
 
 /**
  * Enable the comment admin view.
@@ -46,3 +47,30 @@ function comment_post_update_add_ip_address_setting() {
   $settings->set('log_ip_addresses', TRUE)
     ->save(TRUE);
 }
+
+/**
+ * Update comments to be revisionable.
+ */
+function comment_post_update_make_comment_revisionable(&$sandbox) {
+  $schema_converter = new SqlContentEntityStorageSchemaConverter(
+    'comment',
+    \Drupal::entityTypeManager(),
+    \Drupal::entityDefinitionUpdateManager(),
+    \Drupal::service('entity.last_installed_schema.repository'),
+    \Drupal::keyValue('entity.storage_schema.sql'),
+    \Drupal::database()
+  );
+
+  $schema_converter->convertToRevisionable(
+    $sandbox,
+    [
+      'subject',
+      'name',
+      'mail',
+      'homepage',
+      'hostname',
+      'created',
+      'changed',
+    ]
+  );
+}
diff --git a/core/modules/comment/src/Entity/Comment.php b/core/modules/comment/src/Entity/Comment.php
index bd225d23c1..09f41f4843 100644
--- a/core/modules/comment/src/Entity/Comment.php
+++ b/core/modules/comment/src/Entity/Comment.php
@@ -4,10 +4,8 @@
 
 use Drupal\Component\Utility\Number;
 use Drupal\Core\Cache\Cache;
-use Drupal\Core\Entity\ContentEntityBase;
 use Drupal\comment\CommentInterface;
-use Drupal\Core\Entity\EntityChangedTrait;
-use Drupal\Core\Entity\EntityPublishedTrait;
+use Drupal\Core\Entity\EditorialContentEntityBase;
 use Drupal\Core\Entity\EntityStorageInterface;
 use Drupal\Core\Entity\EntityTypeInterface;
 use Drupal\Core\Field\BaseFieldDefinition;
@@ -43,10 +41,13 @@
  *   },
  *   base_table = "comment",
  *   data_table = "comment_field_data",
+ *   revision_table = "comment_revision",
+ *   revision_data_table = "comment_field_revision",
  *   uri_callback = "comment_uri",
  *   translatable = TRUE,
  *   entity_keys = {
  *     "id" = "cid",
+ *     "revision" = "revision_id",
  *     "bundle" = "comment_type",
  *     "label" = "subject",
  *     "langcode" = "langcode",
@@ -54,6 +55,11 @@
  *     "published" = "status",
  *     "owner" = "uid",
  *   },
+ *   revision_metadata_keys = {
+ *     "revision_user" = "revision_user",
+ *     "revision_created" = "revision_created",
+ *     "revision_log_message" = "revision_log_message",
+ *   },
  *   links = {
  *     "canonical" = "/comment/{comment}",
  *     "delete-form" = "/comment/{comment}/delete",
@@ -68,11 +74,9 @@
  *   }
  * )
  */
-class Comment extends ContentEntityBase implements CommentInterface {
+class Comment extends EditorialContentEntityBase implements CommentInterface {
 
-  use EntityChangedTrait;
   use EntityOwnerTrait;
-  use EntityPublishedTrait;
 
   /**
    * The thread for which a lock was acquired.
@@ -222,7 +226,6 @@ public function permalink() {
   public static function baseFieldDefinitions(EntityTypeInterface $entity_type) {
     /** @var \Drupal\Core\Field\BaseFieldDefinition[] $fields */
     $fields = parent::baseFieldDefinitions($entity_type);
-    $fields += static::publishedBaseFieldDefinitions($entity_type);
     $fields += static::ownerBaseFieldDefinitions($entity_type);
 
     $fields['cid']->setLabel(t('Comment ID'))
@@ -251,6 +254,7 @@ public static function baseFieldDefinitions(EntityTypeInterface $entity_type) {
     $fields['subject'] = BaseFieldDefinition::create('string')
       ->setLabel(t('Subject'))
       ->setTranslatable(TRUE)
+      ->setRevisionable(TRUE)
       ->setSetting('max_length', 64)
       ->setDisplayOptions('form', [
         'type' => 'string_textfield',
@@ -266,18 +270,21 @@ public static function baseFieldDefinitions(EntityTypeInterface $entity_type) {
       ->setLabel(t('Name'))
       ->setDescription(t("The comment author's name."))
       ->setTranslatable(TRUE)
+      ->setRevisionable(TRUE)
       ->setSetting('max_length', 60)
       ->setDefaultValue('');
 
     $fields['mail'] = BaseFieldDefinition::create('email')
       ->setLabel(t('Email'))
       ->setDescription(t("The comment author's email address."))
-      ->setTranslatable(TRUE);
+      ->setTranslatable(TRUE)
+      ->setRevisionable(TRUE);
 
     $fields['homepage'] = BaseFieldDefinition::create('uri')
       ->setLabel(t('Homepage'))
       ->setDescription(t("The comment author's home page address."))
       ->setTranslatable(TRUE)
+      ->setRevisionable(TRUE)
       // URIs are not length limited by RFC 2616, but we can only store 255
       // characters in our comment DB schema.
       ->setSetting('max_length', 255);
@@ -286,18 +293,21 @@ public static function baseFieldDefinitions(EntityTypeInterface $entity_type) {
       ->setLabel(t('Hostname'))
       ->setDescription(t("The comment author's hostname."))
       ->setTranslatable(TRUE)
+      ->setRevisionable(TRUE)
       ->setSetting('max_length', 128)
       ->setDefaultValueCallback(static::class . '::getDefaultHostname');
 
     $fields['created'] = BaseFieldDefinition::create('created')
       ->setLabel(t('Created'))
       ->setDescription(t('The time that the comment was created.'))
-      ->setTranslatable(TRUE);
+      ->setTranslatable(TRUE)
+      ->setRevisionable(TRUE);
 
     $fields['changed'] = BaseFieldDefinition::create('changed')
       ->setLabel(t('Changed'))
       ->setDescription(t('The time that the comment was last edited.'))
-      ->setTranslatable(TRUE);
+      ->setTranslatable(TRUE)
+      ->setRevisionable(TRUE);
 
     $fields['thread'] = BaseFieldDefinition::create('string')
       ->setLabel(t('Thread place'))
@@ -318,6 +328,11 @@ public static function baseFieldDefinitions(EntityTypeInterface $entity_type) {
       ->setSetting('is_ascii', TRUE)
       ->setSetting('max_length', FieldStorageConfig::NAME_MAX_LENGTH);
 
+    // Hide the revision log message field by default.
+    $fields['revision_log_message']->setDisplayOptions('form', [
+      'type' => 'hidden',
+    ]);
+
     return $fields;
   }
 
diff --git a/core/modules/comment/tests/src/Functional/Rest/CommentResourceTestBase.php b/core/modules/comment/tests/src/Functional/Rest/CommentResourceTestBase.php
index 1711d6ebe3..6b056861fb 100644
--- a/core/modules/comment/tests/src/Functional/Rest/CommentResourceTestBase.php
+++ b/core/modules/comment/tests/src/Functional/Rest/CommentResourceTestBase.php
@@ -124,6 +124,9 @@ protected function getExpectedNormalizedEntity() {
       'cid' => [
         ['value' => 1],
       ],
+      'revision_id' => [
+        ['value' => 1],
+      ],
       'uuid' => [
         ['value' => $this->entity->uuid()],
       ],
@@ -194,6 +197,16 @@ protected function getExpectedNormalizedEntity() {
           'value' => '01/',
         ],
       ],
+      'revision_created' => [
+         $this->formatExpectedTimestampItemValues((int) $this->entity->getRevisionCreationTime()),
+      ],
+      'revision_user' => [],
+      'revision_log_message' => [],
+      'revision_translation_affected' => [
+        [
+          'value' => TRUE,
+        ],
+      ],
       'comment_body' => [
         [
           'value' => 'The name "llama" was adopted by European settlers from native Peruvians.',
diff --git a/core/modules/comment/tests/src/Functional/Update/CommentUpdateTest.php b/core/modules/comment/tests/src/Functional/Update/CommentUpdateTest.php
index 73b68cdd70..7eedc4060b 100644
--- a/core/modules/comment/tests/src/Functional/Update/CommentUpdateTest.php
+++ b/core/modules/comment/tests/src/Functional/Update/CommentUpdateTest.php
@@ -2,11 +2,13 @@
 
 namespace Drupal\Tests\comment\Functional\Update;
 
+use Drupal\user\Entity\User;
 use Drupal\FunctionalTests\Update\UpdatePathTestBase;
 
 /**
  * Tests that comment settings are properly updated during database updates.
  *
+ * @group Update
  * @group comment
  * @group legacy
  */
@@ -72,6 +74,55 @@ public function testPublishedEntityKey() {
     $this->assertTrue(\Drupal::database()->schema()->indexExists('comment_field_data', 'comment__status_comment_type'));
   }
 
+  /**
+   * Tests the conversion of comments to be revisionable.
+   *
+   * @see comment_update_8401()
+   * @see comment_post_update_make_comment_revisionable()
+   */
+  public function testConversionToRevisionableAndPublishable() {
+    $this->runUpdates();
+
+    $spanish = \Drupal::languageManager()->getLanguage('es');
+
+    // Log in as user 1.
+    $account = User::load(1);
+    $account->pass_raw = 'drupal';
+    $this->drupalLogin($account);
+
+    // Make sure a translated page exists.
+    $this->drupalGet('node/8', ['language' => $spanish]);
+    // Check for text of two comments.
+    $this->assertText('Hola');
+    $this->assertText('Hello');
+
+    // Check that comments can be created, saved and then loaded.
+    $storage = \Drupal::entityTypeManager()->getStorage('comment');
+    /** @var \Drupal\comment\Entity\Comment $comment */
+    $comment = $storage->create([
+      'entity_id' => 8,
+      'entity_type' => 'node',
+      'field_name' => 'comment',
+      'subject' => 'Test subject',
+      'comment_body' => ['Test comment body'],
+    ]);
+    $comment->save();
+
+    $storage->resetCache();
+    $comment = $storage->loadRevision($comment->getRevisionId());
+
+    $this->assertEqual('Test subject', $comment->label());
+    $this->assertEqual('Test comment body', $comment->comment_body->value);
+    $this->assertTrue($comment->isPublished());
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function replaceUser1() {
+    // Do not replace the user from our dump.
+  }
+
   /**
    * Tests that the comment entity type has an 'owner' entity key.
    *
