diff --git a/core/modules/views/src/Plugin/Derivative/ViewsLocalTask.php b/core/modules/views/src/Plugin/Derivative/ViewsLocalTask.php
index a814984..c15a817 100644
--- a/core/modules/views/src/Plugin/Derivative/ViewsLocalTask.php
+++ b/core/modules/views/src/Plugin/Derivative/ViewsLocalTask.php
@@ -7,6 +7,7 @@
 use Drupal\Component\Plugin\Derivative\DeriverBase;
 use Drupal\Core\Plugin\Discovery\ContainerDeriverInterface;
 use Drupal\Core\Routing\RouteProviderInterface;
+use Drupal\views\ViewExecutable;
 use Drupal\views\Views;
 use Symfony\Component\DependencyInjection\ContainerInterface;
 
@@ -93,9 +94,27 @@ public function getDerivativeDefinitions($base_plugin_definition) {
           'title' => $menu['title'],
         ) + $base_plugin_definition;
 
-        // Default local tasks have themselves as root tab.
         if ($menu['type'] == 'default tab') {
-          $this->derivatives[$plugin_id]['base_route'] = $route_name;
+          $tab_options = $executable->display_handler->getOption('tab_options');
+
+          // If the user has chosen a "Menu tab" as the parent for the default
+          // tab, then it must also be created and the parent relationship must
+          // be established.
+          if (!empty($tab_options['type']) && $tab_options['type'] == 'tab') {
+            $parent_id = $plugin_id . '.parent';
+            $this->derivatives[$parent_id] = array(
+              'route_name' => $route_name,
+              'weight' => $tab_options['weight'],
+              'title' => $tab_options['title'],
+            ) + $base_plugin_definition;
+            // A parent ID is the ID of a local task, which will be slightly
+            // different from the plugin ID after the derivatives are added.
+            $this->derivatives[$plugin_id]['parent_id'] = 'views_view:' . $parent_id;
+          }
+          // Default local tasks have themselves as root tab.
+          else {
+            $this->derivatives[$plugin_id]['base_route'] = $route_name;
+          }
         }
       }
     }
@@ -117,8 +136,8 @@ public function alterLocalTasks(&$local_tasks) {
       $menu = $executable->display_handler->getOption('menu');
 
       // We already have set the base_route for default tabs.
-      if (in_array($menu['type'], array('tab'))) {
-        $plugin_id = 'view.' . $executable->storage->id() . '.' . $display_id;
+      $plugin_id = 'view.' . $executable->storage->id() . '.' . $display_id;
+      if ($menu['type'] == 'tab') {
         $view_route_name = $view_route_names[$executable->storage->id() . '.' . $display_id];
 
         // Don't add a local task for views which override existing routes.
@@ -127,26 +146,51 @@ public function alterLocalTasks(&$local_tasks) {
           continue;
         }
 
-        // Find out the parent route.
-        // @todo Find out how to find both the root and parent tab.
-        $path = $executable->display_handler->getPath();
-        $split = explode('/', $path);
-        array_pop($split);
-        $path = implode('/', $split);
-
-        $pattern = '/' . str_replace('%', '{}', $path);
-        if ($routes = $this->routeProvider->getRoutesByPattern($pattern)) {
-          foreach ($routes->all() as $name => $route) {
-            $local_tasks['views_view:' . $plugin_id]['base_route'] = $name;
-            // Skip after the first found route.
-            break;
-          }
+        $this->applyBaseRoute($executable, $plugin_id, $local_tasks);
+      }
+      // Although the base route for the default tab has been taken care of, we
+      // would still have to adjust the parent tab, if it's being created.
+      elseif ($menu['type'] == 'default tab') {
+        $tab_options = $executable->display_handler->getOption('tab_options');
+        if ($tab_options['type'] == 'tab') {
+          $this->applyBaseRoute($executable, $plugin_id, $local_tasks, TRUE);
         }
       }
     }
   }
 
   /**
+   * Apply the proper base route to a local task.
+   *
+   * @param \Drupal\views\ViewExecutable $view
+   *   The View executable providing the local task.
+   * @param string $plugin_id
+   *   The identifier for the display plugin.
+   * @param array $local_tasks
+   *   The set of all local tasks, which will be adjusted.
+   * @param bool $is_parent
+   *   Notifying that we want a parent local task.
+   */
+  protected function applyBaseRoute(ViewExecutable $view, $plugin_id, &$local_tasks, $is_parent = FALSE) {
+    // Find out the parent route.
+    // @todo Find out how to find both the root and parent tab.
+    $path = $view->display_handler->getPath();
+    $split = explode('/', $path);
+    array_pop($split);
+    $path = implode('/', $split);
+
+    $pattern = '/' . str_replace('%', '{}', $path);
+    if ($routes = $this->routeProvider->getRoutesByPattern($pattern)) {
+      foreach ($routes->all() as $name => $route) {
+        $local_task_key = 'views_view:' . $plugin_id . ($is_parent ? '.parent' : '');
+        $local_tasks[$local_task_key]['base_route'] = $name;
+        // Skip after the first found route.
+        break;
+      }
+    }
+  }
+
+  /**
    * Return a list of all views and display IDs that have a menu entry.
    *
    * @return array
diff --git a/core/modules/views/tests/src/Unit/Plugin/Derivative/ViewsLocalTaskTest.php b/core/modules/views/tests/src/Unit/Plugin/Derivative/ViewsLocalTaskTest.php
index af9a683..c79aef1 100644
--- a/core/modules/views/tests/src/Unit/Plugin/Derivative/ViewsLocalTaskTest.php
+++ b/core/modules/views/tests/src/Unit/Plugin/Derivative/ViewsLocalTaskTest.php
@@ -238,10 +238,20 @@ public function testGetDerivativeDefinitionsWithDefaultLocalTask() {
       ->setMethods(array('getOption'))
       ->disableOriginalConstructor()
       ->getMockForAbstractClass();
-    $display_plugin->expects($this->exactly(2))
+    $display_plugin->expects($this->exactly(4))
       ->method('getOption')
-      ->with('menu')
-      ->will($this->returnValue(array('type' => 'default tab', 'weight' => 12, 'title' => 'Example title')));
+      ->with($this->logicalOr('menu', 'tab_options'))
+      ->will($this->returnValueMap([
+        [
+          'menu',
+          array(
+            'type' => 'default tab',
+            'weight' => 12,
+            'title' => 'Example title',
+          ),
+        ],
+        ['tab_options', array('type' => 'none')],
+      ]));
     $executable->display_handler = $display_plugin;
 
     $result = [['example_view', 'page_1']];
@@ -279,6 +289,113 @@ public function testGetDerivativeDefinitionsWithDefaultLocalTask() {
   }
 
   /**
+   * Tests fetching the derivatives on a view with a default local task.
+   */
+  public function testGetDerivativeDefinitionsWithParentLocalTask() {
+    $executable = $this->getMockBuilder('Drupal\views\ViewExecutable')
+      ->disableOriginalConstructor()
+      ->getMock();
+    $storage = $this->getMockBuilder('Drupal\views\Entity\View')
+      ->disableOriginalConstructor()
+      ->getMock();
+    $storage->expects($this->any())
+      ->method('id')
+      ->will($this->returnValue('example_view'));
+    $storage->expects($this->any())
+      ->method('getExecutable')
+      ->willReturn($executable);
+    $executable->storage = $storage;
+
+    $this->viewStorage->expects($this->any())
+      ->method('load')
+      ->with('example_view')
+      ->willReturn($storage);
+
+    $display_plugin = $this->getMockBuilder('Drupal\views\Plugin\views\display\PathPluginBase')
+      ->setMethods(array('getOption', 'getPath'))
+      ->disableOriginalConstructor()
+      ->getMockForAbstractClass();
+    $display_plugin->expects($this->exactly(4))
+      ->method('getOption')
+      ->with($this->logicalOr('menu', 'tab_options'))
+      ->will($this->returnValueMap([
+        [
+          'menu',
+          array(
+            'type' => 'default tab',
+            'weight' => 12,
+            'title' => 'Example title',
+          ),
+        ],
+        [
+          'tab_options',
+          array(
+            'type' => 'tab',
+            'weight' => 5,
+            'title' => 'Example parent title',
+          ),
+        ],
+      ]));
+    $display_plugin->expects($this->once())
+      ->method('getPath')
+      ->will($this->returnValue('path/example'));
+    $executable->display_handler = $display_plugin;
+
+    $result = [['example_view', 'page_1']];
+    $this->localTaskDerivative->setApplicableMenuViews($result);
+
+    // Mock the view route names state.
+    $view_route_names = array();
+    $view_route_names['example_view.page_1'] = 'view.example_view.page_1';
+    $this->state->expects($this->exactly(2))
+      ->method('get')
+      ->with('views.view_route_names')
+      ->will($this->returnValue($view_route_names));
+
+    // Mock the route provider.
+    $route_collection = new RouteCollection();
+    $route_collection->add('test_route', new Route('/path'));
+    $this->routeProvider->expects($this->any())
+      ->method('getRoutesByPattern')
+      ->with('/path')
+      ->will($this->returnValue($route_collection));
+
+    $definitions = $this->localTaskDerivative->getDerivativeDefinitions($this->baseDefinition);
+    $this->assertCount(2, $definitions);
+    $plugin = $definitions['view.example_view.page_1'];
+    $this->assertEquals('view.example_view.page_1', $plugin['route_name']);
+    $this->assertEquals(12, $plugin['weight']);
+    $this->assertEquals('Example title', $plugin['title']);
+    $this->assertEquals($this->baseDefinition['class'], $plugin['class']);
+    $this->assertEquals('views_view:view.example_view.page_1.parent', $plugin['parent_id']);
+    $parent = $definitions['view.example_view.page_1.parent'];
+    $this->assertEquals('view.example_view.page_1', $parent['route_name']);
+    $this->assertEquals(5, $parent['weight']);
+    $this->assertEquals('Example parent title', $parent['title']);
+    $this->assertEquals($this->baseDefinition['class'], $parent['class']);
+
+    // Setup the prefix of the derivative.
+    $definitions['views_view:view.example_view.page_1'] = $definitions['view.example_view.page_1'];
+    $definitions['views_view:view.example_view.page_1.parent'] = $definitions['view.example_view.page_1.parent'];
+    unset($definitions['view.example_view.page_1'], $definitions['view.example_view.page_1.parent']);
+    $this->localTaskDerivative->alterLocalTasks($definitions);
+
+    $plugin = $definitions['views_view:view.example_view.page_1'];
+    $this->assertCount(2, $definitions);
+    $this->assertEquals('view.example_view.page_1', $plugin['route_name']);
+    $this->assertEquals(12, $plugin['weight']);
+    $this->assertEquals('Example title', $plugin['title']);
+    $this->assertEquals($this->baseDefinition['class'], $plugin['class']);
+    $this->assertEquals('views_view:view.example_view.page_1.parent', $plugin['parent_id']);
+    $parent = $definitions['views_view:view.example_view.page_1.parent'];
+    $this->assertEquals('view.example_view.page_1', $parent['route_name']);
+    $this->assertEquals(5, $parent['weight']);
+    $this->assertEquals('Example parent title', $parent['title']);
+    $this->assertEquals($this->baseDefinition['class'], $parent['class']);
+    $this->assertEquals('test_route', $parent['base_route']);
+  }
+
+  /**
    * Tests fetching the derivatives on a view with a local task and a parent.
    *
    * The parent is defined by another module, not views.
