diff --git a/config/schema/page_manager.schema.yml b/config/schema/page_manager.schema.yml
index 49e5cfc..95b1483 100644
--- a/config/schema/page_manager.schema.yml
+++ b/config/schema/page_manager.schema.yml
@@ -142,3 +142,12 @@ display_variant.plugin.http_status_code:
     redirect_location:
       type: string
       label: 'Redirect location'
+
+display_variant.plugin.layout_builder:
+  type: display_variant.plugin
+  label: 'Layout Builder'
+  mapping:
+    sections:
+      type: sequence
+      sequence:
+        type: layout_builder.section
diff --git a/page_manager.module b/page_manager.module
new file mode 100644
index 0000000..7acfd65
--- /dev/null
+++ b/page_manager.module
@@ -0,0 +1,41 @@
+<?php
+
+/**
+ * @file
+ * Provides a way to place blocks on a custom page.
+ */
+
+use Drupal\page_manager\Entity\LayoutBuilderStorage;
+use Drupal\page_manager\Form\LayoutBuilderForm;
+
+/**
+ * Implements hook_entity_type_build().
+ */
+function page_manager_entity_type_build(array &$entity_types) {
+  if (_page_manager_is_layout_builder_enabled()) {
+    /* @var $entity_types \Drupal\Core\Entity\EntityTypeInterface[] */
+    $entity_types['page_variant']
+      ->setHandlerClass('storage', LayoutBuilderStorage::class)
+      ->setFormClass('layout_builder', LayoutBuilderForm::class);
+  }
+}
+
+/**
+ * Implements hook_display_variant_plugin_alter().
+ */
+function page_manager_display_variant_plugin_alter(array &$definitions) {
+  // Disable the layout builder plugin if layout builder is not enabled.
+  if (!_page_manager_is_layout_builder_enabled()) {
+    unset($definitions['layout_builder']);
+  }
+}
+
+/**
+ * Helper to check if layout builder is enabled.
+ *
+ * @return bool
+ *   TRUE is layout_builder is enabled, otherwise FALSE.
+ */
+function _page_manager_is_layout_builder_enabled() {
+  return Drupal::moduleHandler()->moduleExists('layout_builder');
+}
diff --git a/page_manager_ui/page_manager_ui.module b/page_manager_ui/page_manager_ui.module
index 6812a24..5ffbb32 100644
--- a/page_manager_ui/page_manager_ui.module
+++ b/page_manager_ui/page_manager_ui.module
@@ -139,3 +139,40 @@ function page_manager_ui_local_tasks_alter(&$local_tasks) {
   unset($local_tasks['config_translation.local_tasks:entity.page.config_translation_overview']);
   unset($local_tasks['config_translation.local_tasks:entity.page_variant.config_translation_overview']);
 }
+
+/**
+ * Implements hook_theme_registry_alter().
+ *
+ * @todo Refactor/remove if https://www.drupal.org/project/drupal/issues/3005403 lands.
+ */
+function page_manager_ui_theme_registry_alter(&$theme_registry) {
+  // Seven removes all block contextual links via a preprocess.
+  // Layout builder variants require contextual links to configure blocks.
+  // @see https://www.drupal.org/project/drupal/issues/2487025
+  if (!empty($theme_registry['block']['preprocess functions'])) {
+    $preprocess_functions = &$theme_registry['block']['preprocess functions'];
+
+    // Remove seven's implementation.
+    if ($index = array_search('seven_preprocess_block', $preprocess_functions)) {
+      unset($preprocess_functions[$index]);
+    }
+  }
+}
+
+/**
+ * Implements hook_preprocess_HOOK().
+ *
+ * @todo Refactor/remove if https://www.drupal.org/project/drupal/issues/3005403 lands.
+ */
+function page_manager_ui_preprocess_block(&$variables) {
+  if (Drupal::theme()->getActiveTheme()->getName() === 'seven') {
+    // If active theme is seven and the block has layout_builder contextual
+    // links, do nothing.
+    if (isset($variables['elements']['#contextual_links']['layout_builder_block'])) {
+      return;
+    }
+
+    // Fallback to seven.
+    seven_preprocess_block($variables);
+  }
+}
diff --git a/page_manager_ui/src/Form/PageVariantConfigureForm.php b/page_manager_ui/src/Form/PageVariantConfigureForm.php
index 8008081..2cde00f 100644
--- a/page_manager_ui/src/Form/PageVariantConfigureForm.php
+++ b/page_manager_ui/src/Form/PageVariantConfigureForm.php
@@ -38,7 +38,7 @@ class PageVariantConfigureForm extends FormBase {
     ];
 
     $variant_plugin = $page_variant->getVariantPlugin();
-    $form['variant_settings'] = $variant_plugin->buildConfigurationForm([], (new FormState())->setValues($form_state->getValue('variant_settings', [])));
+    $form['variant_settings'] = $variant_plugin->buildConfigurationForm([], (new FormState())->setValues($form_state->getValue('variant_settings', []) + ['page_variant' => $page_variant]));
     $form['variant_settings']['#tree'] = TRUE;
 
     if (!$page->isNew()) {
diff --git a/src/Entity/LayoutBuilderStorage.php b/src/Entity/LayoutBuilderStorage.php
new file mode 100644
index 0000000..aa73f67
--- /dev/null
+++ b/src/Entity/LayoutBuilderStorage.php
@@ -0,0 +1,41 @@
+<?php
+
+namespace Drupal\page_manager\Entity;
+
+use Drupal\Core\Config\Entity\ConfigEntityStorage;
+use Drupal\Core\Entity\EntityInterface;
+use Drupal\layout_builder\Section;
+
+/**
+ * Provides storage for page manager entities that have layouts.
+ */
+class LayoutBuilderStorage extends ConfigEntityStorage {
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function mapToStorageRecord(EntityInterface $entity) {
+    $record = parent::mapToStorageRecord($entity);
+
+    if (!empty($record['variant_settings']['sections'])) {
+      $record['variant_settings']['sections'] = array_map(function (Section $section) {
+        return $section->toArray();
+      }, $record['variant_settings']['sections']);
+    }
+    return $record;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function mapFromStorageRecords(array $records) {
+    foreach ($records as &$record) {
+      if (!empty($record['variant_settings']['sections'])) {
+        $sections = &$record['variant_settings']['sections'];
+        $sections = array_map([Section::class, 'fromArray'], $sections);
+      }
+    }
+    return parent::mapFromStorageRecords($records);
+  }
+
+}
diff --git a/src/Form/LayoutBuilderForm.php b/src/Form/LayoutBuilderForm.php
new file mode 100644
index 0000000..9c80ec4
--- /dev/null
+++ b/src/Form/LayoutBuilderForm.php
@@ -0,0 +1,140 @@
+<?php
+
+namespace Drupal\page_manager\Form;
+
+use Drupal\Core\Form\FormBase;
+use Drupal\Core\Form\FormStateInterface;
+use Drupal\Core\Plugin\Context\EntityContext;
+use Drupal\Core\TempStore\SharedTempStoreFactory;
+use Drupal\layout_builder\Form\PreviewToggleTrait;
+use Drupal\layout_builder\LayoutTempstoreRepositoryInterface;
+use Drupal\layout_builder\SectionStorage\SectionStorageManager;
+use Symfony\Component\DependencyInjection\ContainerInterface;
+
+/**
+ * Provides a form containing the Layout Builder UI for Page Manager.
+ *
+ * @todo Refactor this after https://www.drupal.org/node/3035189 is resolved.
+ */
+class LayoutBuilderForm extends FormBase {
+
+  use PreviewToggleTrait;
+
+  /**
+   * Layout tempstore repository.
+   *
+   * @var \Drupal\layout_builder\LayoutTempstoreRepositoryInterface
+   */
+  protected $layoutTempstoreRepository;
+
+  /**
+   * The Section Storage Manager.
+   *
+   * @var \Drupal\layout_builder\SectionStorage\SectionStorageManager
+   */
+  protected $sectionStorageManager;
+
+  /**
+   * The section storage.
+   *
+   * @var \Drupal\layout_builder\SectionStorageInterface
+   */
+  protected $sectionStorage;
+
+  /**
+   * The tempstore directory.
+   *
+   * @var \Drupal\Core\TempStore\SharedTempStoreFactory
+   */
+  protected $tempstore;
+
+  /**
+   * Constructs a new LayoutBuilderForm.
+   *
+   * @param \Drupal\layout_builder\LayoutTempstoreRepositoryInterface $layout_tempstore_repository
+   *   The layout tempstore repository.
+   * @param \Drupal\layout_builder\SectionStorage\SectionStorageManager $section_storage_manager
+   *   The section storage manager.
+   * @param \Drupal\Core\TempStore\SharedTempStoreFactory $tempstore
+   *   The tempstore factory.
+   */
+  public function __construct(LayoutTempstoreRepositoryInterface $layout_tempstore_repository, SectionStorageManager $section_storage_manager, SharedTempStoreFactory $tempstore) {
+    $this->layoutTempstoreRepository = $layout_tempstore_repository;
+    $this->sectionStorageManager = $section_storage_manager;
+    $this->tempstore = $tempstore;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public static function create(ContainerInterface $container) {
+    return new static(
+      $container->get('layout_builder.tempstore_repository'),
+      $container->get('plugin.manager.layout_builder.section_storage'),
+      $container->get('tempstore.shared')
+    );
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getFormId() {
+    return 'page_manager_layout_builder_form';
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function buildForm(array $form, FormStateInterface $form_state) {
+    $cached_values = $form_state->getTemporaryValue('wizard');
+    /** @var \Drupal\page_manager\PageVariantInterface $page_variant */
+    $page_variant = $cached_values['page_variant'];
+
+    // If this is a new variant, put it in the tempstore so that we can
+    // retrieve it by id later.
+    // @see \Drupal\page_manager\Plugin\SectionStorage\PageManagerSectionStorage::deriveContextsFromRoute.
+    if ($page_variant->isNew()) {
+      $this->tempstore->get('page_manager.layout_builder')->set($page_variant->id(), $page_variant);
+    }
+
+    $section_storage = $this->sectionStorageManager->load('page_manager', [
+      'entity' => EntityContext::fromEntity($page_variant),
+    ]);
+
+    $this->sectionStorage = $this->layoutTempstoreRepository->get($section_storage);
+
+    $form['preview_toggle'] = $this->buildContentPreviewToggle();
+
+    $form['layout_builder'] = [
+      '#type' => 'layout_builder',
+      '#section_storage' => $this->sectionStorage,
+    ];
+
+    return $form;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function submitForm(array &$form, FormStateInterface $form_state) {
+    $cached_values = $form_state->getTemporaryValue('wizard');
+
+    /** @var \Drupal\page_manager\Entity\PageVariant $page_variant */
+    $page_variant = $this->sectionStorage->getContextValue('entity');
+
+    // Pass down the variant settings and let the plugin handle saving it.
+    /** @var \Drupal\page_manager\Plugin\DisplayVariant\LayoutBuilderDisplayVariant $variant_plugin */
+    $variant_plugin = $cached_values['plugin'];
+    $variant_plugin->setConfiguration($page_variant->get('variant_settings'));
+
+    // The form wizard takes care of saving the variant.
+    // Clear the layout tempstore.
+    $this->layoutTempstoreRepository->delete($this->sectionStorage);
+    $this->messenger()->addMessage($this->t('The layout has been saved.'));
+
+    // Clean up the tempstore.
+    $this->tempstore->get('page_manager.layout_builder')->delete($page_variant->id());
+    $this->tempstore->get('page_manager.page_variant')->delete($page_variant->id());
+  }
+
+}
diff --git a/src/Plugin/DisplayVariant/LayoutBuilderDisplayVariant.php b/src/Plugin/DisplayVariant/LayoutBuilderDisplayVariant.php
new file mode 100644
index 0000000..925f2aa
--- /dev/null
+++ b/src/Plugin/DisplayVariant/LayoutBuilderDisplayVariant.php
@@ -0,0 +1,95 @@
+<?php
+
+namespace Drupal\page_manager\Plugin\DisplayVariant;
+
+use Drupal\Core\Display\VariantBase;
+use Drupal\Core\Form\FormStateInterface;
+use Drupal\ctools\Plugin\PluginWizardInterface;
+use Drupal\layout_builder\LayoutEntityHelperTrait;
+use Drupal\layout_builder\SectionStorage\SectionStorageTrait;
+use Drupal\page_manager\Form\LayoutBuilderForm;
+
+/**
+ * Provides a Layout Builder variant.
+ *
+ * @DisplayVariant(
+ *   id = "layout_builder",
+ *   admin_label = @Translation("Layout Builder")
+ * )
+ */
+class LayoutBuilderDisplayVariant extends VariantBase implements PluginWizardInterface {
+
+  use SectionStorageTrait;
+  use LayoutEntityHelperTrait;
+
+  /**
+   * {@inheritdoc}
+   */
+  public function build() {
+    $build = [];
+    foreach ($this->getSections() as $delta => $section) {
+      $build[$delta] = $section->toRenderArray();
+    }
+    return $build;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function defaultConfiguration() {
+    return parent::defaultConfiguration() + [
+      'sections' => [],
+    ];
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function buildConfigurationForm(array $form, FormStateInterface $form_state) {
+    return $form;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getWizardOperations($cached_values) {
+    $operations = [];
+    $operations['layout_builder'] = [
+      'title' => $this->t('Layout'),
+      'form' => LayoutBuilderForm::class,
+    ];
+
+    return $operations;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function setSections(array $sections) {
+    $this->configuration['sections'] = array_values($sections);
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getSections() {
+    if (!isset($this->configuration['sections'])) {
+      $this->configuration['sections'] = [];
+    }
+    return $this->configuration['sections'];
+  }
+
+  /**
+   * Returns instance of the layout plugin used by this page variant.
+   *
+   * @return \Drupal\Core\Layout\LayoutInterface
+   *   A layout plugin instance.
+   */
+  public function getLayout() {
+    if (!isset($this->layout)) {
+      $this->layout = $this->layoutManager->createInstance($this->configuration['layout'], $this->configuration['layout_settings']);
+    }
+    return $this->layout;
+  }
+
+}
diff --git a/src/Plugin/LayoutBuilderStorage/PageManagerLayoutBuilderStorage.php b/src/Plugin/LayoutBuilderStorage/PageManagerLayoutBuilderStorage.php
new file mode 100644
index 0000000..084ac32
--- /dev/null
+++ b/src/Plugin/LayoutBuilderStorage/PageManagerLayoutBuilderStorage.php
@@ -0,0 +1,122 @@
+<?php
+
+namespace Drupal\panels\Plugin\PanelsStorage;
+
+use Drupal\Core\Access\AccessResult;
+use Drupal\Core\Entity\EntityTypeManagerInterface;
+use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
+use Drupal\Core\Plugin\PluginBase;
+use Drupal\Core\Session\AccountInterface;
+use Drupal\page_manager\Plugin\DisplayVariant\LayoutBuilderDisplayVariant;
+use Symfony\Component\DependencyInjection\ContainerInterface;
+
+/**
+ * A Page Manager storage service that stores Layout Builder displays.
+ */
+class PageManagerLayoutBuilderStorage extends PluginBase implements ContainerFactoryPluginInterface {
+
+  /**
+   * The entity type manager.
+   *
+   * @var \Drupal\Core\Entity\EntityTypeManagerInterface
+   */
+  protected $entityTypeManager;
+
+  /**
+   * Constructs a PageManagerLayoutBuilderStorage.
+   *
+   * @param array $configuration
+   *   A configuration array containing information about the plugin instance.
+   * @param string $plugin_id
+   *   The plugin_id for the plugin instance.
+   * @param mixed $plugin_definition
+   *   The plugin implementation definition.
+   * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
+   *   The entity type manager.
+   */
+  public function __construct(array $configuration, $plugin_id, $plugin_definition, EntityTypeManagerInterface $entity_type_manager) {
+    parent::__construct($configuration, $plugin_id, $plugin_definition);
+    $this->entityTypeManager = $entity_type_manager;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
+    return new static(
+      $configuration,
+      $plugin_id,
+      $plugin_definition,
+      $container->get('entity_type.manager')
+    );
+  }
+
+  /**
+   * Load a page variant entity.
+   *
+   * @param string $id
+   *   The page variant entity's id.
+   *
+   * @return \Drupal\page_manager\PageVariantInterface
+   *   The variant object.
+   *
+   * @throws \Exception
+   */
+  protected function loadPageVariant($id) {
+    return $this->entityTypeManager->getStorage('page_variant')->load($id);
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function save(LayoutBuilderDisplayVariant $lb_display) {
+    $id = $lb_display->getStorageId();
+    if ($id && ($page_variant = $this->loadPageVariant($id))) {
+      $variant_plugin = $page_variant->getVariantPlugin();
+      if (!($variant_plugin instanceof LayoutBuilderDisplayVariant)) {
+        throw new \Exception("Page variant doesn't use a Layout Builder display variant");
+      }
+      $variant_plugin->setConfiguration($lb_display->getConfiguration());
+      $page_variant->save();
+    }
+    else {
+      throw new \Exception("Couldn't find page variant to store Layout Builder display");
+    }
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function load($id) {
+    if ($page_variant = $this->loadPageVariant($id)) {
+      $lb_display = $page_variant->getVariantPlugin();
+
+      // If this page variant doesn't have a Panels display on it, then we treat
+      // it the same as if there was no such page variant.
+      if (!($lb_display instanceof LayoutBuilderDisplayVariant)) {
+        return NULL;
+      }
+
+      // Pass down the contexts because the display has no other way to get them
+      // from the variant.
+      $lb_display->setContexts($page_variant->getContexts());
+
+      return $lb_display;
+    }
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function access($id, $op, AccountInterface $account) {
+    if ($op == 'change layout') {
+      $op = 'update';
+    }
+    if ($page_variant = $this->loadPageVariant($id)) {
+      return $page_variant->access($op, $account, TRUE);
+    }
+
+    return AccessResult::forbidden();
+  }
+
+}
diff --git a/src/Plugin/SectionStorage/PageManagerSectionStorage.php b/src/Plugin/SectionStorage/PageManagerSectionStorage.php
new file mode 100644
index 0000000..97b42df
--- /dev/null
+++ b/src/Plugin/SectionStorage/PageManagerSectionStorage.php
@@ -0,0 +1,233 @@
+<?php
+
+namespace Drupal\page_manager\Plugin\SectionStorage;
+
+use Drupal\Core\Access\AccessResult;
+use Drupal\Core\Cache\RefinableCacheableDependencyInterface;
+use Drupal\Core\Entity\EntityTypeManagerInterface;
+use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
+use Drupal\Core\Plugin\Context\EntityContext;
+use Drupal\Core\Session\AccountInterface;
+use Drupal\Core\TempStore\SharedTempStoreFactory;
+use Drupal\Core\Url;
+use Drupal\layout_builder\Entity\SampleEntityGeneratorInterface;
+use Drupal\layout_builder\Plugin\SectionStorage\SectionStorageBase;
+use Drupal\page_manager\Entity\PageVariant;
+use Drupal\page_manager\Plugin\DisplayVariant\LayoutBuilderDisplayVariant;
+use Symfony\Component\DependencyInjection\ContainerInterface;
+use Symfony\Component\Routing\RouteCollection;
+
+/**
+ * Defines the 'page_manager' section storage type.
+ *
+ * @SectionStorage(
+ *   id = "page_manager",
+ *   context_definitions = {
+ *     "entity" = @ContextDefinition("entity:page_variant"),
+ *   },
+ * )
+ */
+class PageManagerSectionStorage extends SectionStorageBase implements ContainerFactoryPluginInterface {
+
+  /**
+   * The entity type manager.
+   *
+   * @var \Drupal\Core\Entity\EntityTypeManagerInterface
+   */
+  protected $entityTypeManager;
+
+  /**
+   * The sample entity generator.
+   *
+   * @var \Drupal\layout_builder\Entity\SampleEntityGeneratorInterface
+   */
+  protected $sampleEntityGenerator;
+
+  /**
+   * The tempstore factory.
+   *
+   * @var \Drupal\Core\TempStore\SharedTempStoreFactory
+   */
+  protected $tempstore;
+
+  /**
+   * PageManagerSectionStorage constructor.
+   *
+   * @param array $configuration
+   *   The plugin configuration, i.e. an array with configuration values keyed
+   *   by configuration option name. The special key 'context' may be used to
+   *   initialize the defined contexts by setting it to an array of context
+   *   values keyed by context names.
+   * @param string $plugin_id
+   *   The plugin_id for the plugin instance.
+   * @param mixed $plugin_definition
+   *   The plugin implementation definition.
+   * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
+   *   The entity type manager.
+   * @param \Drupal\layout_builder\Entity\SampleEntityGeneratorInterface $sample_entity_generator
+   *   The sample entity generator.
+   * @param \Drupal\Core\TempStore\SharedTempStoreFactory $tempstore
+   *   The tempstore factory.
+   */
+  public function __construct(array $configuration, $plugin_id, $plugin_definition, EntityTypeManagerInterface $entity_type_manager, SampleEntityGeneratorInterface $sample_entity_generator, SharedTempStoreFactory $tempstore) {
+    parent::__construct($configuration, $plugin_id, $plugin_definition);
+
+    $this->entityTypeManager = $entity_type_manager;
+    $this->sampleEntityGenerator = $sample_entity_generator;
+    $this->tempstore = $tempstore;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
+    return new static(
+      $configuration,
+      $plugin_id,
+      $plugin_definition,
+      $container->get('entity_type.manager'),
+      $container->get('layout_builder.sample_entity_generator'),
+      $container->get('tempstore.shared')
+    );
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function getSectionList() {
+    return $this->getContextValue('entity')->getVariantPlugin();
+  }
+
+  /**
+   * Gets the page variant entity.
+   *
+   * @return \Drupal\page_manager\Entity\PageVariant
+   *   The page variant entity.
+   *
+   * @throws \Drupal\Component\Plugin\Exception\PluginException
+   */
+  protected function getPageVariant() {
+    return $this->getContextValue('entity');
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getStorageId() {
+    return $this->getContextValue('entity')->id();
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getRedirectUrl() {
+    return Url::fromUri($this->getPageVariant()->getPage()->getPath());
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getLayoutBuilderUrl($rel = 'view') {
+    return Url::fromRoute("layout_builder.page_manager.view", ['page_variant' => $this->getPageVariant()->id()]);
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function buildRoutes(RouteCollection $collection) {
+    $path = '/admin/structure/page_manager/{page_variant}/layout';
+
+    $options['parameters']['page_variant']['type'] = 'entity:page_variant';
+
+    $options['_admin_route'] = FALSE;
+
+    $this->buildLayoutRoutes($collection, $this->getPluginDefinition(), $path, [], [], $options, '', 'page_variant');
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function deriveContextsFromRoute($value, $definition, $name, array $defaults) {
+    // Try to load from defaults.
+    $entity = $this->extractEntityFromRoute($value, $defaults);
+
+    // Otherwise try the tempstore.
+    if (!$entity) {
+      $entity = $this->tempstore->get('page_manager.layout_builder')->get($value);
+    }
+
+    return [
+      'entity' => EntityContext::fromEntity($entity),
+    ];
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  private function extractEntityFromRoute($value, array $defaults) {
+    if (!empty($value)) {
+      return PageVariant::load($value);
+    }
+
+    return PageVariant::load($defaults['page_variant']);
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function label() {
+    return $this->getPageVariant()->label();
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function save() {
+    $page_variant = $this->getPageVariant();
+    return $page_variant->save();
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function access($operation, AccountInterface $account = NULL, $return_as_object = FALSE) {
+    $result = AccessResult::allowedIf($this->isLayoutBuilderEnabled())->addCacheableDependency($this);
+    return $return_as_object ? $result : $result->isAllowed();
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function isApplicable(RefinableCacheableDependencyInterface $cacheability) {
+    return $this->isLayoutBuilderEnabled();
+  }
+
+  /**
+   * Determines if Layout Builder is enabled.
+   *
+   * @return bool
+   *   TRUE if Layout Builder is enabled, FALSE otherwise.
+   *
+   * @throws \Drupal\Component\Plugin\Exception\PluginException
+   */
+  public function isLayoutBuilderEnabled() {
+    return $this->getContextValue('entity')->getVariantPlugin() instanceof LayoutBuilderDisplayVariant;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getSectionListFromId($id) {
+    // @todo
+    // This is deprecated and can be removed before Drupal 9.0.0.
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function extractIdFromRoute($value, $definition, $name, array $defaults) {
+    // @todo
+    // This is deprecated and can be removed before Drupal 9.0.0.
+  }
+
+}
diff --git a/tests/src/FunctionalJavascript/LayoutBuilderDisplayVariantTest.php b/tests/src/FunctionalJavascript/LayoutBuilderDisplayVariantTest.php
new file mode 100644
index 0000000..7780feb
--- /dev/null
+++ b/tests/src/FunctionalJavascript/LayoutBuilderDisplayVariantTest.php
@@ -0,0 +1,115 @@
+<?php
+
+namespace Drupal\Tests\page_manager\FunctionalJavascript;
+
+use Drupal\FunctionalJavascriptTests\WebDriverTestBase;
+use Drupal\Tests\contextual\FunctionalJavascript\ContextualLinkClickTrait;
+use Drupal\Tests\user\Traits\UserCreationTrait;
+
+/**
+ * Test the layout_builder variant plugin.
+ *
+ * @group page_manager
+ */
+class LayoutBuilderDisplayVariantTest extends WebDriverTestBase {
+
+  use UserCreationTrait;
+  use ContextualLinkClickTrait;
+
+  /**
+   * {@inheritdoc}
+   */
+  protected static $modules = [
+    'layout_builder',
+    'page_manager_ui',
+  ];
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function setUp() {
+    parent::setUp();
+
+    $this->drupalLogin($this->createUser(array_keys($this->container->get('user.permissions')
+      ->getPermissions())));
+  }
+
+  /**
+   * Tests the layout builder variant.
+   */
+  public function testLayoutBuilderVariant() {
+    $this->drupalGet('admin/structure/page_manager/add');
+    $page = $this->getSession()->getPage();
+    $assert_session = $this->assertSession();
+
+    $page->fillField('label', 'Example');
+    $assert_session->waitForElementVisible('css', '.machine-name-value');
+    $this->submitForm([
+      'path' => '/example',
+      'variant_plugin_id' => 'layout_builder',
+    ], t('Next'));
+
+    $this->submitForm([
+      'page_variant_label' => 'Layout Builder',
+    ], t('Next'));
+
+    // Add a two column section.
+    $page->find('css', '.layout-builder__link--add')->click();
+    $assert_session->waitForElementVisible('named', ['link', 'One column']);
+    $this->clickLink('Two column');
+    $assert_session->assertWaitOnAjaxRequest();
+    $page->pressButton('Add section');
+    $assert_session->assertWaitOnAjaxRequest();
+
+    // Place a block in the first region.
+    $page->find('css', '.layout__region--first .layout-builder__link--add')
+      ->click();
+    $assert_session->assertWaitOnAjaxRequest();
+    $this->clickLink('Powered by Drupal');
+    $assert_session->assertWaitOnAjaxRequest();
+    $page->find('css', 'form.layout-builder-add-block .form-submit')->click();
+    $assert_session->assertWaitOnAjaxRequest();
+    $assert_session->pageTextContains('Powered by Drupal');
+
+    // Test content preview.
+    $page->uncheckField('toggle_content_preview');
+    $this->assertNotEmpty($assert_session->waitForElementVisible('css', '.layout-builder-block__content-preview-placeholder-label'));
+
+    $page->pressButton('Finish');
+    $assert_session->pageTextContains('The layout has been saved.');
+
+    // Go the layout builder variant.
+    $this->drupalGet('admin/structure/page_manager/manage/example/page_variant__example-layout_builder-0__layout_builder');
+
+    // Place another block in the first region.
+    $page->find('css', '.layout__region--first .layout-builder__link--add')
+      ->click();
+    $assert_session->assertWaitOnAjaxRequest();
+    $this->clickLink('User account menu');
+    $assert_session->assertWaitOnAjaxRequest();
+    $page->find('css', 'form.layout-builder-add-block .form-submit')->click();
+    $assert_session->assertWaitOnAjaxRequest();
+    $assert_session->pageTextContains('User account menu');
+
+    // Test drag and drop.
+    $page->find('css', '.layout__region--first .menu--account')
+      ->dragTo($page->find('css', '.layout__region--second'));
+    $assert_session->assertWaitOnAjaxRequest();
+
+    // Test contextual links.
+    $assert_session->waitForElement('css', '.block-system-powered-by-block .contextual');
+    $this->clickContextualLink('.block-system-powered-by-block', 'Configure');
+    $this->assertNotEmpty($assert_session->waitForElementVisible('css', '#drupal-off-canvas'));
+
+    // Save page.
+    $page->pressButton('Update and save');
+
+    // Check if block is rendered in the correct region.
+    $this->drupalGet('example');
+    $assert_session->waitForElement('css', '.layout__region--first');
+    $assert_session->elementTextContains('css', '.layout__region--first', 'Powered by Drupal');
+    $assert_session->waitForElement('css', '.layout__region--second');
+    $assert_session->elementTextContains('css', '.layout__region--second', 'User account menu');
+  }
+
+}
