diff --git a/core/modules/path/src/Plugin/Field/FieldType/PathItem.php b/core/modules/path/src/Plugin/Field/FieldType/PathItem.php
index 4d8da7a8ad..76dddc20e8 100644
--- a/core/modules/path/src/Plugin/Field/FieldType/PathItem.php
+++ b/core/modules/path/src/Plugin/Field/FieldType/PathItem.php
@@ -51,23 +51,33 @@ public function preSave() {
    * {@inheritdoc}
    */
   public function postSave($update) {
-    if (!$update) {
-      if ($this->alias) {
-        $entity = $this->getEntity();
-        if ($path = \Drupal::service('path.alias_storage')->save('/' . $entity->urlInfo()->getInternalPath(), $this->alias, $this->getLangcode())) {
-          $this->pid = $path['pid'];
-        }
+    /** @var \Drupal\Core\Path\AliasStorageInterface $alias_storage */
+    $alias_storage = \Drupal::service('path.alias_storage');
+
+    // Only process a non-empty alias.
+    $entity = $this->getEntity();
+    $canonical = '/' . $entity->toUrl()->getInternalPath();
+    if ($entity->getEntityType()->isRevisionable() && !$entity->isDefaultRevision()) {
+      $source = '/' . $entity->toUrl('revision')->getInternalPath();
+    }
+    else {
+      $source = $canonical;
+    }
+
+    if ($this->alias && (!$update || $source != $this->source)) {
+      $default_alias = $alias_storage->load(['source' => $canonical]);
+      if ($default_alias['alias'] != $this->alias && $path = $alias_storage->save($source, $this->alias, $this->getLangcode())) {
+        $this->pid = $path['pid'];
       }
     }
     else {
       // Delete old alias if user erased it.
-      if ($this->pid && !$this->alias) {
-        \Drupal::service('path.alias_storage')->delete(['pid' => $this->pid]);
+      if (!$this->alias) {
+        $alias_storage->delete(['source' => $source]);
       }
       // Only save a non-empty alias.
-      elseif ($this->alias) {
-        $entity = $this->getEntity();
-        \Drupal::service('path.alias_storage')->save('/' . $entity->urlInfo()->getInternalPath(), $this->alias, $this->getLangcode(), $this->pid);
+      elseif ($source) {
+        $alias_storage->save($source, $this->alias, $this->getLangcode(), $this->pid);
       }
     }
   }
diff --git a/core/modules/path/src/Plugin/Field/FieldWidget/PathWidget.php b/core/modules/path/src/Plugin/Field/FieldWidget/PathWidget.php
index b31af4694b..dbc2525c83 100644
--- a/core/modules/path/src/Plugin/Field/FieldWidget/PathWidget.php
+++ b/core/modules/path/src/Plugin/Field/FieldWidget/PathWidget.php
@@ -28,11 +28,17 @@ public function formElement(FieldItemListInterface $items, $delta, array $elemen
     $entity = $items->getEntity();
     $path = [];
     if (!$entity->isNew()) {
-      $conditions = ['source' => '/' . $entity->urlInfo()->getInternalPath()];
       if ($items->getLangcode() != LanguageInterface::LANGCODE_NOT_SPECIFIED) {
-        $conditions['langcode'] = $items->getLangcode();
+        $conditions = ['langcode' => $items->getLangcode()];
+      }
+      if ($entity->getEntityType()->isRevisionable() && !$entity->isDefaultRevision()) {
+        $conditions['source'] = '/' . $entity->toUrl('revision')->getInternalPath();
+        $path = \Drupal::service('path.alias_storage')->load($conditions);
+      }
+      if (empty($path)) {
+        $conditions['source'] = '/' . $entity->toUrl()->getInternalPath();
+        $path = \Drupal::service('path.alias_storage')->load($conditions);
       }
-      $path = \Drupal::service('path.alias_storage')->load($conditions);
       if ($path === FALSE) {
         $path = [];
       }
diff --git a/core/modules/path/tests/src/Functional/PathContentModerationTest.php b/core/modules/path/tests/src/Functional/PathContentModerationTest.php
new file mode 100644
index 0000000000..b9d9f8305e
--- /dev/null
+++ b/core/modules/path/tests/src/Functional/PathContentModerationTest.php
@@ -0,0 +1,103 @@
+<?php
+
+namespace Drupal\Tests\path\Functional;
+
+use Drupal\node\Entity\NodeType;
+use Drupal\Tests\BrowserTestBase;
+use Drupal\workflows\Entity\Workflow;
+
+/**
+ * Tests path aliases with Content Moderation.
+ *
+ * @group path
+ */
+class PathContentModerationTest extends BrowserTestBase {
+
+  /**
+   * Modules to install.
+   *
+   * @var array
+   */
+  public static $modules = ['node', 'path', 'content_moderation'];
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function setUp() {
+    parent::setUp();
+
+    // Created a content type.
+    $node_type = NodeType::create(['name' => 'moderated', 'type' => 'moderated']);
+    $node_type->save();
+
+    // Set the content type as moderated.
+    $workflow = Workflow::load('editorial');
+    $workflow->getTypePlugin()->addEntityTypeAndBundle('node', 'moderated');
+    $workflow->save();
+
+    $this->drupalLogin($this->rootUser);
+  }
+
+  public function testNodePathAlias() {
+    // Create some moderated content with a path alias.
+    $this->drupalPostForm('node/add/moderated', [
+      'title[0][value]' => 'moderated content',
+      'path[0][alias]' => '/moderated-content',
+    ], t('Save and Publish'));
+    $node = $this->getNodeByTitle('moderated content');
+
+    $this->drupalGet('/moderated-content');
+    $this->assertSession()->pageTextContains('moderated content');
+
+    // Add a forward revision with the same alias.
+    $this->drupalPostForm('node/' . $node->id() . '/edit', [
+      'title[0][value]' => 'forward revision',
+      'path[0][alias]' => '/moderated-content',
+    ], t('Save and Create New Draft'));
+
+    // Check the alias still shows the default content.
+    $this->drupalGet('/moderated-content');
+    $this->assertSession()->pageTextNotContains('forward revision');
+    $this->assertSession()->pageTextContains('moderated content');
+
+    // Add a third revision, updating alias.
+    $this->drupalPostForm('node/' . $node->id() . '/edit', [
+      'title[0][value]' => 'revision three',
+      'path[0][alias]' => '/revision-three',
+    ], t('Save and Create New Draft'));
+
+    // Check both aliases return what we'd expect.
+    $this->drupalGet('/revision-three');
+    $this->assertSession()->pageTextNotContains('moderated content');
+    $this->assertSession()->pageTextNotContains('forward revision');
+    $this->assertSession()->pageTextContains('revision three');
+    $this->drupalGet('/moderated-content');
+    $this->assertSession()->pageTextNotContains('forward revision');
+    $this->assertSession()->pageTextContains('moderated content');
+    $this->assertSession()->pageTextNotContains('revision three');
+
+    // Add another forward revision with no alias.
+    $this->drupalPostForm('node/' . $node->id() . '/edit', [
+      'title[0][value]' => 'revision four',
+      'path[0][alias]' => '',
+    ], t('Save and Create New Draft'));
+
+    // The first two aliases should still work, and the revision with no alias
+    // should work on the revision path.
+    $this->drupalGet('/node/1/revisions/4/view');
+    $this->assertSession()->pageTextNotContains('moderated content');
+    $this->assertSession()->pageTextNotContains('forward revision');
+    $this->assertSession()->pageTextNotContains('revision three');
+    $this->assertSession()->pageTextContains('revision four');
+    $this->drupalGet('/revision-three');
+    $this->assertSession()->pageTextNotContains('moderated content');
+    $this->assertSession()->pageTextNotContains('forward revision');
+    $this->assertSession()->pageTextContains('revision three');
+    $this->assertSession()->pageTextNotContains('revision four');
+    $this->drupalGet('/moderated-content');
+    $this->assertSession()->pageTextNotContains('forward revision');
+    $this->assertSession()->pageTextContains('moderated content');
+    $this->assertSession()->pageTextNotContains('revision three');
+    $this->assertSession()->pageTextNotContains('revision four');
+  }
+}
\ No newline at end of file
