diff --git a/core/modules/content_moderation/content_moderation.module b/core/modules/content_moderation/content_moderation.module
index 201fc4566949ae04e35483fbf222b68a13805162..09ade0d56583e9057cf78b03af4fb7f4e9f4daea 100644
--- a/core/modules/content_moderation/content_moderation.module
+++ b/core/modules/content_moderation/content_moderation.module
@@ -91,6 +91,33 @@ function content_moderation_entity_update(EntityInterface $entity) {
     ->entityUpdate($entity);
 }
 
+/**
+ * Implements hook_entity_delete().
+ */
+function content_moderation_entity_delete(EntityInterface $entity) {
+  return \Drupal::service('class_resolver')
+    ->getInstanceFromDefinition(EntityOperations::class)
+    ->entityDelete($entity);
+}
+
+/**
+ * Implements hook_entity_revision_delete().
+ */
+function content_moderation_entity_revision_delete(EntityInterface $entity) {
+  return \Drupal::service('class_resolver')
+    ->getInstanceFromDefinition(EntityOperations::class)
+    ->entityRevisionDelete($entity);
+}
+
+/**
+ * Implements hook_entity_translation_delete().
+ */
+function content_moderation_entity_translation_delete(EntityInterface $translation) {
+  return \Drupal::service('class_resolver')
+    ->getInstanceFromDefinition(EntityOperations::class)
+    ->entityTranslationDelete($translation);
+}
+
 /**
  * Implements hook_form_alter().
  */
diff --git a/core/modules/content_moderation/src/Entity/ContentModerationState.php b/core/modules/content_moderation/src/Entity/ContentModerationState.php
index 39b0ff4e2fc5a7a7202a6d1ae92979b239dac20d..aedcb5fadeea9b04b864c6e10d2493eaa1fdce70 100644
--- a/core/modules/content_moderation/src/Entity/ContentModerationState.php
+++ b/core/modules/content_moderation/src/Entity/ContentModerationState.php
@@ -4,6 +4,7 @@
 
 use Drupal\content_moderation\ContentModerationStateInterface;
 use Drupal\Core\Entity\ContentEntityBase;
+use Drupal\Core\Entity\EntityInterface;
 use Drupal\Core\Entity\EntityTypeInterface;
 use Drupal\Core\Field\BaseFieldDefinition;
 use Drupal\Core\TypedData\TranslatableInterface;
@@ -142,6 +143,44 @@ public static function updateOrCreateFromEntity(ContentModerationState $content_
     $content_moderation_state->realSave();
   }
 
+  /**
+   * Loads a content moderation state entity.
+   *
+   * @param \Drupal\Core\Entity\EntityInterface $entity
+   *   A moderated entity object.
+   *
+   * @return \Drupal\content_moderation\ContentModerationStateInterface|null
+   *   The related content moderation state or NULL if none could be found.
+   *
+   * @internal
+   *   This method should only be called by code directly handling the
+   *   ContentModerationState entity objects.
+   */
+  public static function loadFromModeratedEntity(EntityInterface $entity) {
+    $content_moderation_state = NULL;
+    $moderation_info = \Drupal::service('content_moderation.moderation_information');
+
+    if ($moderation_info->isModeratedEntity($entity)) {
+      /** @var \Drupal\Core\Entity\ContentEntityInterface $entity */
+      $storage = \Drupal::entityTypeManager()->getStorage('content_moderation_state');
+
+      $ids = $storage->getQuery()
+        ->condition('content_entity_type_id', $entity->getEntityTypeId())
+        ->condition('content_entity_id', $entity->id())
+        ->condition('workflow', $moderation_info->getWorkflowForEntity($entity)->id())
+        ->condition('content_entity_revision_id', $entity->getLoadedRevisionId())
+        ->allRevisions()
+        ->execute();
+
+      if ($ids) {
+        /** @var \Drupal\content_moderation\ContentModerationStateInterface $content_moderation_state */
+        $content_moderation_state = $storage->loadRevision(key($ids));
+      }
+    }
+
+    return $content_moderation_state;
+  }
+
   /**
    * Default value callback for the 'uid' base field definition.
    *
diff --git a/core/modules/content_moderation/src/EntityOperations.php b/core/modules/content_moderation/src/EntityOperations.php
index f726582635038e13d8ed9af0efe127fd9b5ec2b6..22e901b03ea58ef65ce64050d95516db7dde8320 100644
--- a/core/modules/content_moderation/src/EntityOperations.php
+++ b/core/modules/content_moderation/src/EntityOperations.php
@@ -154,31 +154,16 @@ public function entityUpdate(EntityInterface $entity) {
    *   The entity to update or create a moderation state for.
    */
   protected function updateOrCreateFromEntity(EntityInterface $entity) {
-    $moderation_state = $entity->moderation_state->value;
-    $workflow = $this->moderationInfo->getWorkflowForEntity($entity);
     /** @var \Drupal\Core\Entity\ContentEntityInterface $entity */
-    if (!$moderation_state) {
-      $moderation_state = $workflow->getTypePlugin()->getInitialState($workflow, $entity)->id();
-    }
-
-    // @todo what if $entity->moderation_state is null at this point?
-    $entity_type_id = $entity->getEntityTypeId();
-    $entity_id = $entity->id();
     $entity_revision_id = $entity->getRevisionId();
+    $workflow = $this->moderationInfo->getWorkflowForEntity($entity);
+    $content_moderation_state = ContentModerationStateEntity::loadFromModeratedEntity($entity);
 
-    $storage = $this->entityTypeManager->getStorage('content_moderation_state');
-    $entities = $storage->loadByProperties([
-      'content_entity_type_id' => $entity_type_id,
-      'content_entity_id' => $entity_id,
-      'workflow' => $workflow->id(),
-    ]);
-
-    /** @var \Drupal\content_moderation\ContentModerationStateInterface $content_moderation_state */
-    $content_moderation_state = reset($entities);
     if (!($content_moderation_state instanceof ContentModerationStateInterface)) {
+      $storage = $this->entityTypeManager->getStorage('content_moderation_state');
       $content_moderation_state = $storage->create([
-        'content_entity_type_id' => $entity_type_id,
-        'content_entity_id' => $entity_id,
+        'content_entity_type_id' => $entity->getEntityTypeId(),
+        'content_entity_id' => $entity->id(),
         // Make sure that the moderation state entity has the same language code
         // as the moderated entity.
         'langcode' => $entity->language()->getId(),
@@ -203,6 +188,13 @@ protected function updateOrCreateFromEntity(EntityInterface $entity) {
     }
 
     // Create the ContentModerationState entity for the inserted entity.
+    $moderation_state = $entity->moderation_state->value;
+    /** @var \Drupal\Core\Entity\ContentEntityInterface $entity */
+    if (!$moderation_state) {
+      $moderation_state = $workflow->getTypePlugin()->getInitialState($workflow, $entity)->id();
+    }
+
+    // @todo what if $entity->moderation_state is null at this point?
     $content_moderation_state->set('content_entity_revision_id', $entity_revision_id);
     $content_moderation_state->set('moderation_state', $moderation_state);
     ContentModerationStateEntity::updateOrCreateFromEntity($content_moderation_state);
@@ -224,6 +216,61 @@ protected function setLatestRevision(EntityInterface $entity) {
     );
   }
 
+  /**
+   * Hook bridge.
+   *
+   * @param \Drupal\Core\Entity\EntityInterface $entity
+   *   The entity being deleted.
+   *
+   * @see hook_entity_delete()
+   */
+  public function entityDelete(EntityInterface $entity) {
+    $content_moderation_state = ContentModerationStateEntity::loadFromModeratedEntity($entity);
+    if ($content_moderation_state) {
+      $content_moderation_state->delete();
+    }
+  }
+
+  /**
+   * Hook bridge.
+   *
+   * @param \Drupal\Core\Entity\EntityInterface $entity
+   *   The entity revision being deleted.
+   *
+   * @see hook_entity_revision_delete()
+   */
+  public function entityRevisionDelete(EntityInterface $entity) {
+    /** @var \Drupal\Core\Entity\ContentEntityInterface $entity */
+    if (!$entity->isDefaultRevision()) {
+      $content_moderation_state = ContentModerationStateEntity::loadFromModeratedEntity($entity);
+      if ($content_moderation_state) {
+        $this->entityTypeManager
+          ->getStorage('content_moderation_state')
+          ->deleteRevision($content_moderation_state->getRevisionId());
+      }
+    }
+  }
+
+  /**
+   * Hook bridge.
+   *
+   * @param \Drupal\Core\Entity\EntityInterface $translation
+   *   The entity translation being deleted.
+   *
+   * @see hook_entity_translation_delete()
+   */
+  public function entityTranslationDelete(EntityInterface $translation) {
+    /** @var \Drupal\Core\Entity\ContentEntityInterface $translation */
+    if (!$translation->isDefaultTranslation()) {
+      $langcode = $translation->language()->getId();
+      $content_moderation_state = ContentModerationStateEntity::loadFromModeratedEntity($translation);
+      if ($content_moderation_state && $content_moderation_state->hasTranslation($langcode)) {
+        $content_moderation_state->removeTranslation($langcode);
+        ContentModerationStateEntity::updateOrCreateFromEntity($content_moderation_state);
+      }
+    }
+  }
+
   /**
    * Act on entities being assembled before rendering.
    *
diff --git a/core/modules/content_moderation/tests/src/Kernel/ContentModerationStateTest.php b/core/modules/content_moderation/tests/src/Kernel/ContentModerationStateTest.php
index 713e5b51684e6afc60261a9aae573ea4fe74bccb..5e237f39fb6e9b09ea35be448bcf32e4196c97b4 100644
--- a/core/modules/content_moderation/tests/src/Kernel/ContentModerationStateTest.php
+++ b/core/modules/content_moderation/tests/src/Kernel/ContentModerationStateTest.php
@@ -3,13 +3,13 @@
 namespace Drupal\Tests\content_moderation\Kernel;
 
 use Drupal\content_moderation\Entity\ContentModerationState;
+use Drupal\Core\Entity\EntityInterface;
 use Drupal\Core\Entity\EntityPublishedInterface;
 use Drupal\Core\Entity\EntityStorageException;
 use Drupal\Core\Language\LanguageInterface;
 use Drupal\entity_test\Entity\EntityTestBundle;
 use Drupal\entity_test\Entity\EntityTestRev;
 use Drupal\entity_test\Entity\EntityTestWithBundle;
-use Drupal\Core\Entity\EntityInterface;
 use Drupal\KernelTests\KernelTestBase;
 use Drupal\language\Entity\ConfigurableLanguage;
 use Drupal\node\Entity\Node;
@@ -29,6 +29,7 @@ class ContentModerationStateTest extends KernelTestBase {
   public static $modules = [
     'entity_test',
     'node',
+    'block',
     'block_content',
     'media',
     'media_test_source',
@@ -74,17 +75,20 @@ protected function setUp() {
   }
 
   /**
-   * Tests basic monolingual content moderation through the API.
+   * Sets up a bundle entity type for the specified entity type, if needed.
    *
-   * @dataProvider basicModerationTestCases
+   * @param string $entity_type_id
+   *   The entity type identifier.
+   *
+   * @return string
+   *   The bundle identifier.
    */
-  public function testBasicModeration($entity_type_id) {
+  protected function setupBundleEntityType($entity_type_id) {
     // Make the 'entity_test_with_bundle' entity type revisionable.
     if ($entity_type_id == 'entity_test_with_bundle') {
       $this->setEntityTestWithBundleKeys(['revision' => 'revision_id']);
     }
 
-    $entity_storage = $this->entityTypeManager->getStorage($entity_type_id);
     $bundle_id = $entity_type_id;
     $bundle_entity_type_id = $this->entityTypeManager->getDefinition($entity_type_id)->getBundleEntityType();
     if ($bundle_entity_type_id) {
@@ -112,6 +116,19 @@ public function testBasicModeration($entity_type_id) {
     $workflow->getTypePlugin()->addEntityTypeAndBundle($entity_type_id, $bundle_id);
     $workflow->save();
 
+    return $bundle_id;
+  }
+
+  /**
+   * Tests basic monolingual content moderation through the API.
+   *
+   * @dataProvider basicModerationTestCases
+   */
+  public function testBasicModeration($entity_type_id) {
+    $bundle_id = $this->setupBundleEntityType($entity_type_id);
+
+    /** @var \Drupal\Core\Entity\ContentEntityInterface $entity */
+    $entity_storage = $this->entityTypeManager->getStorage($entity_type_id);
     $entity = $entity_storage->create([
       'title' => 'Test title',
       $this->entityTypeManager->getDefinition($entity_type_id)->getKey('bundle') => $bundle_id,
@@ -213,6 +230,69 @@ public function basicModerationTestCases() {
     ];
   }
 
+  /**
+   * Tests removal of content moderation state entity field data.
+   *
+   * @dataProvider basicModerationTestCases
+   */
+  public function testContentModerationStateDataRemoval($entity_type_id) {
+    $bundle_id = $this->setupBundleEntityType($entity_type_id);
+
+    // Test content moderation state deletion.
+    $entity_storage = $this->entityTypeManager->getStorage($entity_type_id);
+    /** @var \Drupal\Core\Entity\ContentEntityInterface $entity */
+    $entity = $entity_storage->create([
+      'title' => 'Test title',
+      $this->entityTypeManager->getDefinition($entity_type_id)->getKey('bundle') => $bundle_id,
+    ]);
+    $entity->save();
+    $entity = $this->reloadEntity($entity);
+    $entity->delete();
+    $content_moderation_state = ContentModerationState::loadFromModeratedEntity($entity);
+    $this->assertFalse($content_moderation_state);
+
+    // Test content moderation state revision deletion.
+    /** @var \Drupal\Core\Entity\ContentEntityInterface $entity2 */
+    $entity2 = $entity_storage->create([
+      'title' => 'Test title',
+      $this->entityTypeManager->getDefinition($entity_type_id)->getKey('bundle') => $bundle_id,
+    ]);
+    $entity2->save();
+    $revision = clone $entity2;
+    $revision->isDefaultRevision(FALSE);
+    $content_moderation_state = ContentModerationState::loadFromModeratedEntity($revision);
+    $this->assertTrue($content_moderation_state);
+    $entity2 = $this->reloadEntity($entity2);
+    $entity2->setNewRevision(TRUE);
+    $entity2->save();
+    $entity_storage->deleteRevision($revision->getRevisionId());
+    $content_moderation_state = ContentModerationState::loadFromModeratedEntity($revision);
+    $this->assertFalse($content_moderation_state);
+    $content_moderation_state = ContentModerationState::loadFromModeratedEntity($entity2);
+    $this->assertTrue($content_moderation_state);
+
+    // Test content moderation state translation deletion.
+    if ($this->entityTypeManager->getDefinition($entity_type_id)->isTranslatable()) {
+      /** @var \Drupal\Core\Entity\ContentEntityInterface $entity3 */
+      $entity3 = $entity_storage->create([
+        'title' => 'Test title',
+        $this->entityTypeManager->getDefinition($entity_type_id)->getKey('bundle') => $bundle_id,
+      ]);
+      $langcode = 'it';
+      ConfigurableLanguage::createFromLangcode($langcode)
+        ->save();
+      $entity3->save();
+      $translation = $entity3->addTranslation($langcode, ['title' => 'Titolo test']);
+      $translation->save();
+      $content_moderation_state = ContentModerationState::loadFromModeratedEntity($entity3);
+      $this->assertTrue($content_moderation_state->hasTranslation($langcode));
+      $entity3->removeTranslation($langcode);
+      $entity3->save();
+      $content_moderation_state = ContentModerationState::loadFromModeratedEntity($entity3);
+      $this->assertFalse($content_moderation_state->hasTranslation($langcode));
+    }
+  }
+
   /**
    * Tests basic multilingual content moderation through the API.
    */