diff --git a/core/modules/book/src/BookManager.php b/core/modules/book/src/BookManager.php
index 3e14c40..17bc0d9 100644
--- a/core/modules/book/src/BookManager.php
+++ b/core/modules/book/src/BookManager.php
@@ -249,6 +249,13 @@ public function updateOutline(NodeInterface $node) {
       return FALSE;
     }
 
+    // Prevent changes to the book outline if the node being saved is not the
+    // default revision.
+    if (!$node->isDefaultRevision()) {
+      drupal_set_message($this->t('The book outline could not be changed because a non-default revision (for example: a new draft revision) of the content has been created.'), 'error');
+      return FALSE;
+    }
+
     if (!empty($node->book['bid'])) {
       if ($node->book['bid'] == 'new') {
         // New nodes that are their own book.
diff --git a/core/modules/book/tests/src/Functional/BookContentModerationTest.php b/core/modules/book/tests/src/Functional/BookContentModerationTest.php
new file mode 100644
index 0000000..6838297
--- /dev/null
+++ b/core/modules/book/tests/src/Functional/BookContentModerationTest.php
@@ -0,0 +1,88 @@
+<?php
+
+namespace Drupal\Tests\book\Functional;
+
+use Drupal\workflows\Entity\Workflow;
+
+/**
+ * Tests Book and Content Moderation integration.
+ *
+ * @group book
+ */
+class BookContentModerationTest extends BookTest {
+
+  /**
+   * Modules to install.
+   *
+   * @var array
+   */
+  public static $modules = ['book', 'block', 'book_test', 'content_moderation'];
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function setUp() {
+    parent::setUp();
+
+    $workflow = Workflow::load('editorial');
+    $workflow->getTypePlugin()->addEntityTypeAndBundle('node', 'book');
+    $workflow->save();
+
+    // We need a user with additional content moderation permissions.
+    $this->bookAuthor = $this->drupalCreateUser(['create new books', 'create book content', 'edit own book content', 'add content to books', 'access printer-friendly version', 'view any unpublished content', 'use editorial transition create_new_draft', 'use editorial transition publish']);
+  }
+
+  /**
+   * Tests that book drafts can not modify the book outline.
+   */
+  public function testBookWithForwardRevisions() {
+    // Create two books.
+    $book_1_nodes = $this->createBook();
+    $book_1 = $this->book;
+
+    $this->createBook();
+    $book_2 = $this->book;
+
+    $this->drupalLogin($this->bookAuthor);
+
+    // Check that book pages display along with the correct outlines.
+    $this->book = $book_1;
+    $this->checkBookNode($book_1, [$book_1_nodes[0], $book_1_nodes[3], $book_1_nodes[4]], FALSE, FALSE, $book_1_nodes[0], []);
+    $this->checkBookNode($book_1_nodes[0], [$book_1_nodes[1], $book_1_nodes[2]], $book_1, $book_1, $book_1_nodes[1], [$book_1]);
+
+    // Try to move Node 2 to a different parent.
+    $edit['book[pid]'] = $book_1_nodes[3]->id();
+    $this->drupalPostForm('node/' . $book_1_nodes[1]->id() . '/edit', $edit, t('Save and Create New Draft'));
+
+    $this->assertSession()->pageTextContains('The book outline could not be changed because a non-default revision (for example: a new draft revision) of the content has been created.');
+
+    // Check that the book outline did not change.
+    $this->book = $book_1;
+    $this->checkBookNode($book_1, [$book_1_nodes[0], $book_1_nodes[3], $book_1_nodes[4]], FALSE, FALSE, $book_1_nodes[0], []);
+    $this->checkBookNode($book_1_nodes[0], [$book_1_nodes[1], $book_1_nodes[2]], $book_1, $book_1, $book_1_nodes[1], [$book_1]);
+
+    // Try to move Node 2 to a different book.
+    $edit['book[bid]'] = $book_2->id();
+    $this->drupalPostForm('node/' . $book_1_nodes[1]->id() . '/edit', $edit, t('Save and Create New Draft'));
+
+    $this->assertSession()->pageTextContains('The book outline could not be changed because a non-default revision (for example: a new draft revision) of the content has been created.');
+
+    // Check that the book outline did not change.
+    $this->book = $book_1;
+    $this->checkBookNode($book_1, [$book_1_nodes[0], $book_1_nodes[3], $book_1_nodes[4]], FALSE, FALSE, $book_1_nodes[0], []);
+    $this->checkBookNode($book_1_nodes[0], [$book_1_nodes[1], $book_1_nodes[2]], $book_1, $book_1, $book_1_nodes[1], [$book_1]);
+
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function createBookNode($book_nid, $parent = NULL, $submit = NULL) {
+    // This test has Content Moderation enabled so we have a different value for
+    // the submit button.
+    $submit = t('Save and Publish');
+
+    return parent::createBookNode($book_nid, $parent, $submit);
+  }
+
+}
diff --git a/core/modules/book/tests/src/Functional/BookTest.php b/core/modules/book/tests/src/Functional/BookTest.php
index 66edec9..d7771f0 100644
--- a/core/modules/book/tests/src/Functional/BookTest.php
+++ b/core/modules/book/tests/src/Functional/BookTest.php
@@ -335,15 +335,20 @@ public function generateOutlinePattern($nodes) {
    *   A book node ID or set to 'new' to create a new book.
    * @param int|null $parent
    *   (optional) Parent book reference ID. Defaults to NULL.
+   * @param string $submit
+   *   (optional) Value of the submit button whose click is to be emulated.
+   *   Defaults to 'Save'.
    *
    * @return \Drupal\node\NodeInterface
    *   The created node.
    */
-  public function createBookNode($book_nid, $parent = NULL) {
+  public function createBookNode($book_nid, $parent = NULL, $submit = NULL) {
     // $number does not use drupal_static as it should not be reset
     // since it uniquely identifies each call to createBookNode().
     static $number = 0; // Used to ensure that when sorted nodes stay in same order.
 
+    $submit = $submit ?: t('Save');
+
     $edit = [];
     $edit['title[0][value]'] = str_pad($number, 2, '0', STR_PAD_LEFT) . ' - SimpleTest test node ' . $this->randomMachineName(10);
     $edit['body[0][value]'] = 'SimpleTest test body ' . $this->randomMachineName(32) . ' ' . $this->randomMachineName(32);
@@ -353,13 +358,13 @@ public function createBookNode($book_nid, $parent = NULL) {
       $this->drupalPostForm('node/add/book', $edit, t('Change book (update list of parents)'));
 
       $edit['book[pid]'] = $parent;
-      $this->drupalPostForm(NULL, $edit, t('Save'));
+      $this->drupalPostForm(NULL, $edit, $submit);
       // Make sure the parent was flagged as having children.
       $parent_node = \Drupal::entityManager()->getStorage('node')->loadUnchanged($parent);
       $this->assertFalse(empty($parent_node->book['has_children']), 'Parent node is marked as having children');
     }
     else {
-      $this->drupalPostForm('node/add/book', $edit, t('Save'));
+      $this->drupalPostForm('node/add/book', $edit, $submit);
     }
 
     // Check to make sure the book node was created.
diff --git a/core/modules/book/tests/src/Kernel/BookForwardRevisionTest.php b/core/modules/book/tests/src/Kernel/BookForwardRevisionTest.php
new file mode 100644
index 0000000..c15aaf8
--- /dev/null
+++ b/core/modules/book/tests/src/Kernel/BookForwardRevisionTest.php
@@ -0,0 +1,79 @@
+<?php
+
+namespace Drupal\Tests\book\Kernel;
+
+use Drupal\node\Entity\Node;
+use Drupal\node\Entity\NodeType;
+use Drupal\KernelTests\KernelTestBase;
+
+/**
+ * Tests that the Book module handles forward revisions correctly.
+ *
+ * @group book
+ */
+class BookForwardRevisionTest extends KernelTestBase {
+
+  /**
+   * Modules to enable.
+   *
+   * @var array
+   */
+  public static $modules = ['system', 'user', 'field', 'filter', 'text', 'node', 'book'];
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function setUp() {
+    parent::setUp();
+
+    $this->installEntitySchema('user');
+    $this->installEntitySchema('node');
+    $this->installSchema('book', ['book']);
+    $this->installSchema('node', ['node_access']);
+    $this->installConfig(['node', 'book', 'field']);
+  }
+
+  /**
+   * Tests the book_system_info_alter() method.
+   */
+  public function testBookWithForwardRevisions() {
+    $content_type = NodeType::create([
+      'type' => $this->randomMachineName(),
+      'name' => $this->randomString(),
+    ]);
+    $content_type->save();
+    $book_config = $this->config('book.settings');
+    $allowed_types = $book_config->get('allowed_types');
+    $allowed_types[] = $content_type->id();
+    $book_config->set('allowed_types', $allowed_types)->save();
+
+    // Create two top-level books a child.
+    $book_1 = Node::create(['title' => $this->randomString(), 'type' => $content_type->id()]);
+    $book_1->book['bid'] = 'new';
+    $book_1->save();
+
+    $book_2 = Node::create(['title' => $this->randomString(), 'type' => $content_type->id()]);
+    $book_2->book['bid'] = 'new';
+    $book_2->save();
+
+    $child = Node::create(['title' => $this->randomString(), 'type' => $content_type->id()]);
+    $child->book['bid'] = $book_1->id();
+    $child->book['pid'] = $book_1->id();
+    $child->save();
+
+    // Try to move the child to a different book while saving it as a forward
+    // revision.
+    /** @var \Drupal\book\BookManagerInterface $book_manager */
+    $book_manager = $this->container->get('book.manager');
+
+    // First, check that the API doesn't allow us to change the book outline for
+    // forward revisions.
+    $child->book['bid'] = $book_2->id();
+    $child->setNewRevision(TRUE);
+    $child->isDefaultRevision(FALSE);
+
+    $return = $book_manager->updateOutline($child);
+    $this->assertFalse($return, 'A forward revision can not change the book outline.');
+  }
+
+}
