diff --git a/src/Form/LayoutPluginSelector.php b/src/Form/LayoutPluginSelector.php
new file mode 100644
index 0000000..b38e06f
--- /dev/null
+++ b/src/Form/LayoutPluginSelector.php
@@ -0,0 +1,56 @@
+<?php
+/**
+ * @file
+ * Contains LayoutPluginSelector.php
+ */
+
+namespace Drupal\panels\Form;
+
+
+use Drupal\Core\Form\FormBase;
+use Drupal\Core\Form\FormStateInterface;
+use Drupal\layout_plugin\Plugin\Layout\LayoutPluginManagerInterface;
+use Symfony\Component\DependencyInjection\ContainerInterface;
+
+class LayoutPluginSelector extends FormBase {
+
+  /**
+   * @var \Drupal\layout_plugin\Plugin\Layout\LayoutPluginManagerInterface
+   */
+  protected $manager;
+
+  public static function create(ContainerInterface $container) {
+    return new static($container->get('plugin.manager.layout_plugin'));
+  }
+
+  public function __construct(LayoutPluginManagerInterface $manager) {
+    $this->manager = $manager;
+  }
+
+  public function getFormId() {
+    return 'panels_layout_selection_form';
+  }
+
+  public function buildForm(array $form, FormStateInterface $form_state) {
+    $cached_values = $form_state->getTemporaryValue('wizard');
+    $variant_plugin = $cached_values['plugin'];
+    $options = [];
+    foreach ($this->manager->getDefinitions() as $plugin_id => $definition) {
+      $options[$plugin_id] = $definition['label'];
+    }
+    $form['layout'] = [
+      '#title' => $this->t('Choose a layout'),
+      '#type' => 'select',
+      '#options' => $options,
+      '#default_value' => $variant_plugin->getConfiguration()['layout'],
+    ];
+    return $form;
+  }
+
+  public function submitForm(array &$form, FormStateInterface $form_state) {
+    $cached_values = $form_state->getTemporaryValue('wizard');
+    $variant_plugin = $cached_values['plugin'];
+    $variant_plugin->setLayout($form_state->getValue('layout'));
+  }
+
+}
diff --git a/src/Plugin/DisplayVariant/PanelsDisplayVariant.php b/src/Plugin/DisplayVariant/PanelsDisplayVariant.php
index aa34cf2..eb664c3 100644
--- a/src/Plugin/DisplayVariant/PanelsDisplayVariant.php
+++ b/src/Plugin/DisplayVariant/PanelsDisplayVariant.php
@@ -17,11 +17,13 @@ use Drupal\Core\Form\FormStateInterface;
 use Drupal\Core\Plugin\Context\ContextHandlerInterface;
 use Drupal\Core\Session\AccountInterface;
 use Drupal\Core\Utility\Token;
-use Drupal\ctools\Plugin\BlockPluginCollection;
 use Drupal\ctools\Plugin\DisplayVariant\BlockDisplayVariant;
+use Drupal\ctools\Plugin\PluginWizardInterface;
 use Drupal\layout_plugin\Layout;
 use Drupal\layout_plugin\Plugin\Layout\LayoutInterface;
 use Drupal\layout_plugin\Plugin\Layout\LayoutPluginManagerInterface;
+use Drupal\page_manager_ui\Form\VariantPluginContentForm;
+use Drupal\panels\Form\LayoutPluginSelector;
 use Drupal\panels\Plugin\DisplayBuilder\DisplayBuilderInterface;
 use Drupal\panels\Plugin\DisplayBuilder\DisplayBuilderManagerInterface;
 use Symfony\Component\DependencyInjection\ContainerInterface;
@@ -34,7 +36,20 @@ use Symfony\Component\DependencyInjection\ContainerInterface;
  *   admin_label = @Translation("Panels")
  * )
  */
-class PanelsDisplayVariant extends BlockDisplayVariant {
+class PanelsDisplayVariant extends BlockDisplayVariant implements PluginWizardInterface {
+
+  public function getWizardOperations($cached_values) {
+    return [
+      'layout' => [
+        'title' => $this->t('Layout'),
+        'form' => LayoutPluginSelector::class
+      ],
+      'content' => [
+        'title' => $this->t('Content'),
+        'form' => VariantPluginContentForm::class
+      ]
+    ];
+  }
 
   /**
    * The module handler.
@@ -407,7 +422,7 @@ class PanelsDisplayVariant extends BlockDisplayVariant {
    *   An array with two values: the new form array and form state object.
    */
   protected function getLayoutSettingsForm(array &$form, FormStateInterface $form_state) {
-    $layout_settings_form = NestedArray::getValue($form, array_merge($form['#variant_array_parents'], ['layout_settings_wrapper', 'layout_settings']));
+    $layout_settings_form = NestedArray::getValue($form, ['layout_settings_wrapper', 'layout_settings']);
     $layout_settings_form_state = (new FormState())->setValues($form_state->getValue('layout_settings'));
     return [$layout_settings_form, $layout_settings_form_state];
   }
@@ -547,4 +562,18 @@ class PanelsDisplayVariant extends BlockDisplayVariant {
     return $data;
   }
 
+  /**
+   * {@inheritdoc}
+   */
+  public function __sleep() {
+    $vars = parent::__sleep();
+
+    // Gathered contexts objects should not be serialized.
+    if (($key = array_search('contexts', $vars)) !== FALSE) {
+      unset($vars[$key]);
+    }
+
+    return $vars;
+  }
+
 }
diff --git a/src/Tests/PanelsTest.php b/src/Tests/PanelsTest.php
index b83ab4b..7f7ecd7 100644
--- a/src/Tests/PanelsTest.php
+++ b/src/Tests/PanelsTest.php
@@ -7,6 +7,7 @@
 
 namespace Drupal\panels\Tests;
 
+use Drupal\Component\Render\FormattableMarkup;
 use Drupal\simpletest\WebTestBase;
 
 /**
@@ -24,7 +25,7 @@ class PanelsTest extends WebTestBase {
   /**
    * {@inheritdoc}
    */
-  public static $modules = ['block', 'page_manager', 'page_manager_ui', 'panels_test', 'layout_plugin_example'];
+  public static $modules = ['block', 'page_manager_ui', 'panels_test', 'layout_plugin_example', 'node'];
 
   /**
    * {@inheritdoc}
@@ -32,6 +33,8 @@ class PanelsTest extends WebTestBase {
   protected function setUp() {
     parent::setUp();
 
+    $this->drupalCreateContentType(['type' => 'article', 'name' => 'Article']);
+
     $this->drupalPlaceBlock('local_tasks_block');
     $this->drupalPlaceBlock('local_actions_block');
     $this->drupalPlaceBlock('system_branding_block');
@@ -40,7 +43,12 @@ class PanelsTest extends WebTestBase {
     \Drupal::service('theme_handler')->install(['bartik', 'classy']);
     $this->config('system.theme')->set('admin', 'classy')->save();
 
-    $this->drupalLogin($this->drupalCreateUser(['administer pages', 'access administration pages', 'view the administration theme']));
+    $this->drupalLogin($this->drupalCreateUser([
+      'administer pages',
+      'access administration pages',
+      'view the administration theme',
+      'create article content',
+    ]));
   }
 
   /**
@@ -48,49 +56,87 @@ class PanelsTest extends WebTestBase {
    */
   public function testLayoutSettings() {
     // Create new page.
-    $this->drupalGet('admin/structure/page_manager/add');
     $edit = [
       'id' => 'foo',
-      'label' => 'foo',
-      'path' => 'testing',
+      'label' => 'Foo',
+      'path' => 'foo/{node}',
+      'variant_plugin_id' => 'panels_variant',
+      'use_admin_theme' => TRUE,
+      'description' => 'This is our first test page.',
     ];
-    $this->drupalPostForm(NULL, $edit, 'Save');
+    $this->drupalPostForm('admin/structure/page_manager/add', $edit, 'Next');
+
+    // Map the parameter with the Node entity.
+    $this->clickLink('Edit');
+    $edit = [
+      'type' => 'entity:node',
+    ];
+    $this->drupalPostForm(NULL, $edit, 'Update parameter');
+    $this->assertText('The Node parameter has been updated.');
+    $this->drupalPostForm(NULL, [], 'Next');
 
-    // Add variant with a layout that has settings.
-    $this->clickLink('Add new variant');
-    $this->clickLink('Panels');
+    // Configure the variant.
     $edit = [
-      'id' => 'panels_1',
-      'label' => 'Default',
+      'variant_settings[page_title]' => 'Sample Panels page',
       'variant_settings[layout]' => 'layout_example_test',
     ];
-    $this->drupalPostForm(NULL, $edit, 'Save');
+    $this->drupalPostForm(NULL, $edit, 'Next');
 
-    // Add a block.
+    // Skip the layout step.
+    // @TODO We should remove this step since the layout can be selected
+    // at the previous step.
+    $this->drupalPostForm(NULL, [], 'Next');
+
+    // Place the Node entity display block within the layout.
     $this->clickLink('Add new block');
-    $this->clickLink('Powered by Drupal');
+    $this->clickLink('Entity view (Content)');
     $edit = [
       'region' => 'top',
     ];
     $this->drupalPostForm(NULL, $edit, 'Add block');
 
-    // Check the default value and change a layout setting.
+    // Finish the wizard.
+    $this->drupalPostForm(NULL, [], 'Finish');
+    $this->assertRaw(new FormattableMarkup('Saved the %label Page.', ['%label' => 'Foo']));
+
+    // Test the page.
+    $node = $this->drupalCreateNode(['type' => 'article']);
+    $this->drupalGet('foo/' . $node->id());
+    $this->assertResponse(200);
+    $this->assertText($node->getTitle());
+
+    // Check that the default value of a layout setting is present.
+    $this->drupalGet('admin/structure/page_manager/manage/foo/page_variant__foo-panels_variant-0__general');
     $this->assertText('Blah');
     $this->assertFieldByName("variant_settings[layout_settings][setting_1]", "Default");
+
+    // Change the value of the field within Layout Settings.
     $edit = [
       'variant_settings[layout_settings][setting_1]' => 'Abracadabra',
     ];
     $this->drupalPostForm(NULL, $edit, 'Save');
 
     // Go back to the variant edit form and see that the setting stuck.
-    $this->drupalGet('admin/structure/page_manager/manage/foo/variant/panels_1');
+    $this->drupalGet('admin/structure/page_manager/manage/foo/page_variant__foo-panels_variant-0__general');
     $this->assertFieldByName("variant_settings[layout_settings][setting_1]", "Abracadabra");
 
     // View the page and make sure the setting is present.
-    $this->drupalGet('testing');
+    $this->drupalGet('foo/' . $node->id());
     $this->assertText('Blah:');
     $this->assertText('Abracadabra');
-    $this->assertText('Powered by Drupal');
+
+    // Selecting a different layout should update the Layout Settings fieldset
+    // via AJAX.
+    $edit = [
+      'variant_settings[layout]' => 'onecol',
+    ];
+    $this->drupalPostAjaxForm(NULL, $edit, 'variant_settings[layout]');
+    $this->assertNoText('Blah');
+    $edit = [
+      'variant_settings[layout]' => 'layout_example_test',
+    ];
+    $this->drupalPostAjaxForm(NULL, $edit, 'variant_settings[layout]');
+    $this->assertNoText('Blah');
   }
 
 }
