diff --git a/core/modules/layout_builder/src/Element/LayoutBuilder.php b/core/modules/layout_builder/src/Element/LayoutBuilder.php
index 99970b208f..74b7b273c1 100644
--- a/core/modules/layout_builder/src/Element/LayoutBuilder.php
+++ b/core/modules/layout_builder/src/Element/LayoutBuilder.php
@@ -8,6 +8,8 @@
 use Drupal\Core\Plugin\PluginFormInterface;
 use Drupal\Core\Render\Element;
 use Drupal\Core\Render\Element\RenderElement;
+use Drupal\Core\Session\AccountInterface;
+use Drupal\Core\TempStore\Lock;
 use Drupal\Core\Url;
 use Drupal\layout_builder\Context\LayoutBuilderContextTrait;
 use Drupal\layout_builder\LayoutTempstoreRepositoryInterface;
@@ -40,6 +42,13 @@ class LayoutBuilder extends RenderElement implements ContainerFactoryPluginInter
    */
   protected $messenger;
 
+  /**
+   * The current user.
+   *
+   * @var \Drupal\Core\Session\AccountInterface
+   */
+  protected $currentUser;
+
   /**
    * Constructs a new LayoutBuilder.
    *
@@ -53,11 +62,14 @@ class LayoutBuilder extends RenderElement implements ContainerFactoryPluginInter
    *   The layout tempstore repository.
    * @param \Drupal\Core\Messenger\MessengerInterface $messenger
    *   The messenger service.
+   * @param \Drupal\Core\Session\AccountInterface $current_user
+   *   The current user.
    */
-  public function __construct(array $configuration, $plugin_id, $plugin_definition, LayoutTempstoreRepositoryInterface $layout_tempstore_repository, MessengerInterface $messenger) {
+  public function __construct(array $configuration, $plugin_id, $plugin_definition, LayoutTempstoreRepositoryInterface $layout_tempstore_repository, MessengerInterface $messenger, AccountInterface $current_user) {
     parent::__construct($configuration, $plugin_id, $plugin_definition);
     $this->layoutTempstoreRepository = $layout_tempstore_repository;
     $this->messenger = $messenger;
+    $this->currentUser = $current_user;
   }
 
   /**
@@ -69,7 +81,8 @@ public static function create(ContainerInterface $container, array $configuratio
       $plugin_id,
       $plugin_definition,
       $container->get('layout_builder.tempstore_repository'),
-      $container->get('messenger')
+      $container->get('messenger'),
+      $container->get('current_user')
     );
   }
 
@@ -95,6 +108,27 @@ public function preRender($element) {
     return $element;
   }
 
+  /**
+   * Gets the lock message.
+   *
+   * @param \Drupal\layout_builder\SectionStorageInterface $section_storage
+   *   The section storage.
+   * @param \Drupal\Core\TempStore\Lock $lock
+   *   The lock object.
+   *
+   * @return string|\Drupal\Core\StringTranslation\TranslatableMarkup
+   *   The lock message.
+   */
+  protected function lockMessage(SectionStorageInterface $section_storage, Lock $lock) {
+    $message_array = [
+      '#type' => 'break_lock_link',
+      '#label' => $this->t('layout'),
+      '#lock' => $lock,
+      '#url' => $section_storage->getLayoutBuilderUrl('discard_changes'),
+    ];
+    return \Drupal::service('renderer')->render($message_array);
+  }
+
   /**
    * Renders the Layout UI.
    *
@@ -105,7 +139,19 @@ public function preRender($element) {
    *   A render array.
    */
   protected function layout(SectionStorageInterface $section_storage) {
-    $this->prepareLayout($section_storage);
+    // If the layout has pending changes, add a warning.
+    if ($lock = $this->layoutTempstoreRepository->getLock($section_storage)) {
+      if ($this->currentUser->id() === $lock->getOwnerId()) {
+        $this->messenger->addWarning($this->t('You have unsaved changes.'));
+      }
+      else {
+        $this->messenger->addWarning($this->lockMessage($section_storage, $lock));
+        return [];
+      }
+    }
+    else {
+      $this->prepareLayout($section_storage);
+    }
 
     $output = [];
     if ($this->isAjax()) {
@@ -135,12 +181,8 @@ protected function layout(SectionStorageInterface $section_storage) {
    *   The section storage.
    */
   protected function prepareLayout(SectionStorageInterface $section_storage) {
-    // If the layout has pending changes, add a warning.
-    if ($this->layoutTempstoreRepository->has($section_storage)) {
-      $this->messenger->addWarning($this->t('You have unsaved changes.'));
-    }
     // Only add sections if the layout is new and empty.
-    elseif ($section_storage->count() === 0) {
+    if ($section_storage->count() === 0) {
       $sections = [];
       // If this is an empty override, copy the sections from the corresponding
       // default.
diff --git a/core/modules/layout_builder/src/Form/DefaultsEntityForm.php b/core/modules/layout_builder/src/Form/DefaultsEntityForm.php
index 111973a44e..5b79e18517 100644
--- a/core/modules/layout_builder/src/Form/DefaultsEntityForm.php
+++ b/core/modules/layout_builder/src/Form/DefaultsEntityForm.php
@@ -94,6 +94,13 @@ public function getEntityFromRouteMatch(RouteMatchInterface $route_match, $entit
    */
   protected function actions(array $form, FormStateInterface $form_state) {
     $actions = parent::actions($form, $form_state);
+
+    // Restrict access to actions if the form is locked by another user.
+    $lock = $this->layoutTempstoreRepository->getLock($this->sectionStorage);
+    if ($lock && $lock->getOwnerId() !== $this->currentUser()->id()) {
+      $actions['#access'] = FALSE;
+    }
+
     $actions['submit']['#value'] = $this->t('Save layout');
     $actions['#weight'] = -1000;
 
diff --git a/core/modules/layout_builder/src/Form/DiscardLayoutChangesForm.php b/core/modules/layout_builder/src/Form/DiscardLayoutChangesForm.php
index 311bc7df3a..d26ff6a669 100644
--- a/core/modules/layout_builder/src/Form/DiscardLayoutChangesForm.php
+++ b/core/modules/layout_builder/src/Form/DiscardLayoutChangesForm.php
@@ -5,6 +5,7 @@
 use Drupal\Core\Form\ConfirmFormBase;
 use Drupal\Core\Form\FormStateInterface;
 use Drupal\Core\Messenger\MessengerInterface;
+use Drupal\Core\Session\AccountInterface;
 use Drupal\layout_builder\LayoutTempstoreRepositoryInterface;
 use Drupal\layout_builder\SectionStorageInterface;
 use Symfony\Component\DependencyInjection\ContainerInterface;
@@ -28,6 +29,13 @@ class DiscardLayoutChangesForm extends ConfirmFormBase {
    */
   protected $messenger;
 
+  /**
+   * The current user.
+   *
+   * @var \Drupal\Core\Session\AccountInterface
+   */
+  protected $currentUser;
+
   /**
    * The section storage.
    *
@@ -35,6 +43,13 @@ class DiscardLayoutChangesForm extends ConfirmFormBase {
    */
   protected $sectionStorage;
 
+  /**
+   * Indicates if the owner of the lock is the current user or not.
+   *
+   * @var bool
+   */
+  protected $isOwnerCurrentUser;
+
   /**
    * Constructs a new DiscardLayoutChangesForm.
    *
@@ -42,10 +57,13 @@ class DiscardLayoutChangesForm extends ConfirmFormBase {
    *   The layout tempstore repository.
    * @param \Drupal\Core\Messenger\MessengerInterface $messenger
    *   The messenger service.
+   * @param \Drupal\Core\Session\AccountInterface $current_user
+   *   The current user.
    */
-  public function __construct(LayoutTempstoreRepositoryInterface $layout_tempstore_repository, MessengerInterface $messenger) {
+  public function __construct(LayoutTempstoreRepositoryInterface $layout_tempstore_repository, MessengerInterface $messenger, AccountInterface $current_user) {
     $this->layoutTempstoreRepository = $layout_tempstore_repository;
     $this->messenger = $messenger;
+    $this->currentUser = $current_user;
   }
 
   /**
@@ -54,7 +72,8 @@ public function __construct(LayoutTempstoreRepositoryInterface $layout_tempstore
   public static function create(ContainerInterface $container) {
     return new static(
       $container->get('layout_builder.tempstore_repository'),
-      $container->get('messenger')
+      $container->get('messenger'),
+      $container->get('current_user')
     );
   }
 
@@ -69,14 +88,14 @@ public function getFormId() {
    * {@inheritdoc}
    */
   public function getQuestion() {
-    return $this->t('Are you sure you want to discard your layout changes?');
+    return $this->isOwnerCurrentUser ? $this->t('Are you sure you want to discard your layout changes?') : $this->t('Are you sure you want to break the lock on the layout changes?');
   }
 
   /**
    * {@inheritdoc}
    */
   public function getCancelUrl() {
-    return $this->sectionStorage->getRedirectUrl();
+    return $this->sectionStorage->getLayoutBuilderUrl();
   }
 
   /**
@@ -84,6 +103,10 @@ public function getCancelUrl() {
    */
   public function buildForm(array $form, FormStateInterface $form_state, SectionStorageInterface $section_storage = NULL) {
     $this->sectionStorage = $section_storage;
+    $lock = $this->layoutTempstoreRepository->getLock($section_storage);
+    // The current user is considered the owner if there are no changes made or
+    // if they are the ones who made the changes.
+    $this->isOwnerCurrentUser = !$lock ? TRUE : $lock->getOwnerId() === $this->currentUser()->id();
     return parent::buildForm($form, $form_state);
   }
 
@@ -95,7 +118,10 @@ public function submitForm(array &$form, FormStateInterface $form_state) {
 
     $this->messenger->addMessage($this->t('The changes to the layout have been discarded.'));
 
-    $form_state->setRedirectUrl($this->getCancelUrl());
+    // If the user is discarding their own changes, redirect as usual. If they
+    // are breaking the lock of another user's changes, redirect them back to
+    // the Layout Builder UI to make their own changes.
+    $form_state->setRedirectUrl($this->isOwnerCurrentUser ? $this->sectionStorage->getRedirectUrl() : $this->sectionStorage->getLayoutBuilderUrl());
   }
 
 }
diff --git a/core/modules/layout_builder/src/Form/OverridesEntityForm.php b/core/modules/layout_builder/src/Form/OverridesEntityForm.php
index c2a28aa2f9..914fe64fb9 100644
--- a/core/modules/layout_builder/src/Form/OverridesEntityForm.php
+++ b/core/modules/layout_builder/src/Form/OverridesEntityForm.php
@@ -139,6 +139,13 @@ public function save(array $form, FormStateInterface $form_state) {
    */
   protected function actions(array $form, FormStateInterface $form_state) {
     $actions = parent::actions($form, $form_state);
+
+    // Restrict access to actions if the form is locked by another user.
+    $lock = $this->layoutTempstoreRepository->getLock($this->sectionStorage);
+    if ($lock && $lock->getOwnerId() !== $this->currentUser()->id()) {
+      $actions['#access'] = FALSE;
+    }
+
     $actions['submit']['#value'] = $this->t('Save layout');
     $actions['delete']['#access'] = FALSE;
     $actions['#weight'] = -1000;
diff --git a/core/modules/layout_builder/src/LayoutTempstoreRepository.php b/core/modules/layout_builder/src/LayoutTempstoreRepository.php
index d8fbb47f29..54819de5d1 100644
--- a/core/modules/layout_builder/src/LayoutTempstoreRepository.php
+++ b/core/modules/layout_builder/src/LayoutTempstoreRepository.php
@@ -45,6 +45,14 @@ public function get(SectionStorageInterface $section_storage) {
     return $section_storage;
   }
 
+  /**
+   * {@inheritdoc}
+   */
+  public function getLock(SectionStorageInterface $section_storage) {
+    $key = $this->getKey($section_storage);
+    return $this->getTempstore($section_storage)->getMetadata($key);
+  }
+
   /**
    * {@inheritdoc}
    */
diff --git a/core/modules/layout_builder/src/LayoutTempstoreRepositoryInterface.php b/core/modules/layout_builder/src/LayoutTempstoreRepositoryInterface.php
index 67dc59ca99..379742f631 100644
--- a/core/modules/layout_builder/src/LayoutTempstoreRepositoryInterface.php
+++ b/core/modules/layout_builder/src/LayoutTempstoreRepositoryInterface.php
@@ -27,6 +27,17 @@ interface LayoutTempstoreRepositoryInterface {
    */
   public function get(SectionStorageInterface $section_storage);
 
+  /**
+   * Returns the lock object.
+   *
+   * @param \Drupal\layout_builder\SectionStorageInterface $section_storage
+   *   The section storage.
+   *
+   * @return \Drupal\Core\TempStore\Lock|null
+   *   The lock object, or NULL if none exists.
+   */
+  public function getLock(SectionStorageInterface $section_storage);
+
   /**
    * Stores this section storage in tempstore.
    *
diff --git a/core/modules/layout_builder/tests/src/Functional/LayoutBuilderTest.php b/core/modules/layout_builder/tests/src/Functional/LayoutBuilderTest.php
index 77dcb64ac5..28ee8f640c 100644
--- a/core/modules/layout_builder/tests/src/Functional/LayoutBuilderTest.php
+++ b/core/modules/layout_builder/tests/src/Functional/LayoutBuilderTest.php
@@ -484,6 +484,56 @@ public function testLayoutBuilderUiFullViewMode() {
     $page->pressButton('Confirm');
   }
 
+  /**
+   * Tests concurrent editing of the layout by two users.
+   */
+  public function testConcurrentEditing() {
+    $assert_session = $this->assertSession();
+    $page = $this->getSession()->getPage();
+
+    $user1 = $this->drupalCreateUser([
+      'configure any layout',
+      'administer node display',
+    ]);
+    $user2 = $this->drupalCreateUser([
+      'configure any layout',
+      'administer node display',
+    ]);
+
+    $this->drupalLogin($user1);
+    $this->drupalPostForm('admin/structure/types/manage/bundle_with_section_field/display/default', ['layout[enabled]' => TRUE], 'Save');
+
+    $this->drupalGet('admin/structure/types/manage/bundle_with_section_field/display/default/layout');
+    $assert_session->elementsCount('css', '.layout-builder--layout', 1);
+    $assert_session->elementNotExists('css', '.layout--twocol-section');
+    $page->clickLink('Add Section');
+    $page->clickLink('Two column');
+    $page->pressButton('Add section');
+    $assert_session->elementsCount('css', '.layout-builder--layout', 2);
+    $assert_session->elementExists('css', '.layout--twocol-section');
+    $assert_session->pageTextContains('You have unsaved changes.');
+    $assert_session->buttonExists('Save layout');
+    $assert_session->linkExists('Discard changes');
+
+    $this->drupalLogin($user2);
+    $this->drupalGet('admin/structure/types/manage/bundle_with_section_field/display/default/layout');
+    $assert_session->elementsCount('css', '.layout-builder--layout', 0);
+    $assert_session->pageTextContains(sprintf('This layout is being edited by user %s, and is therefore locked from editing by others.', $user1->getDisplayName()));
+    $assert_session->pageTextNotContains('You have unsaved changes.');
+    $assert_session->buttonNotExists('Save layout');
+    $assert_session->linkNotExists('Discard changes');
+
+    $page->clickLink('break this lock');
+    $page->pressButton('Confirm');
+    $assert_session->elementsCount('css', '.layout-builder--layout', 1);
+    $assert_session->elementNotExists('css', '.layout--twocol-section');
+    $assert_session->pageTextNotContains(sprintf('This layout is being edited by user %s, and is therefore locked from editing by others.', $user1->getDisplayName()));
+    $assert_session->pageTextNotContains('You have unsaved changes.');
+    $assert_session->pageTextContains('The changes to the layout have been discarded.');
+    $assert_session->buttonExists('Save layout');
+    $assert_session->linkExists('Discard changes');
+  }
+
   /**
    * {@inheritdoc}
    */
