diff --git a/core/lib/Drupal/Core/Menu/Plugin/Derivative/StaticLocalTaskDeriver.php b/core/lib/Drupal/Core/Menu/Plugin/Derivative/StaticLocalTaskDeriver.php
new file mode 100644
index 0000000..de01c95
--- /dev/null
+++ b/core/lib/Drupal/Core/Menu/Plugin/Derivative/StaticLocalTaskDeriver.php
@@ -0,0 +1,114 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\Core\Menu\Plugin\Derivative\StaticLocalTaskDeriver.
+ */
+
+namespace Drupal\Core\Menu\Plugin\Derivative;
+
+use Drupal\Core\Extension\ModuleHandlerInterface;
+use Drupal\Core\Plugin\Discovery\ContainerDerivativeInterface;
+use Drupal\Component\Plugin\Exception\PluginException;
+use Drupal\Core\StringTranslation\TranslationManager;
+use Drupal\Component\Utility\String;
+use Drupal\Component\Discovery\YamlDiscovery;
+use Symfony\Component\DependencyInjection\ContainerInterface;
+
+/**
+ * Provides plugin derivatives for local tasks provided in YAML files.
+ */
+class StaticLocalTaskDeriver implements ContainerDerivativeInterface {
+
+  /**
+   * List of derivative definitions.
+   *
+   * @var array
+   */
+  protected $derivatives = array();
+
+  /**
+   * The base plugin ID.
+   *
+   * @var string
+   */
+  protected $basePluginId;
+
+  /**
+   * The module handler.
+   *
+   * @var \Drupal\Core\Extension\ModuleHandlerInterface
+   */
+  protected $moduleHandler;
+
+  /**
+   * The translation manager.
+   *
+   * @var \Drupal\Core\StringTranslation\TranslationManager
+   */
+  protected $translationManager;
+
+  /**
+   * {@inheritdoc}
+   */
+  public static function create(ContainerInterface $container, $base_plugin_id) {
+    return new static(
+      $base_plugin_id,
+      $container->get('module_handler'),
+      $container->get('string_translation')
+    );
+  }
+
+  /**
+   * Constructs a StaticLocalTaskDeriver object.
+   *
+   * @param string $base_plugin_id
+   *   The base plugin ID.
+   * @param\Drupal\Core\Extension\ModuleHandlerInterface $module_handler
+   *   The module handler.
+   * @param \Drupal\Core\StringTranslation\TranslationManager translation_manager
+   *   The translation manager.
+   */
+  public function __construct($base_plugin_id, ModuleHandlerInterface $module_handler, TranslationManager $translation_manager) {
+    $this->basePluginId = $base_plugin_id;
+    $this->moduleHandler = $module_handler;
+    $this->translationManager = $translation_manager;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getDerivativeDefinition($derivative_id, array $base_plugin_definition) {
+    if (!empty($this->derivatives) && !empty($this->derivatives[$derivative_id])) {
+      return $this->derivatives[$derivative_id];
+    }
+    $this->getDerivativeDefinitions($base_plugin_definition);
+    return $this->derivatives[$derivative_id];
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getDerivativeDefinitions(array $base_plugin_definition) {
+    $yaml_discovery = new YamlDiscovery('local_tasks', $this->moduleHandler->getModuleDirectories());
+    $required_keys = array('title' => 1, 'route_name' => 1, 'tab_root_id' => 1);
+
+    foreach ($yaml_discovery->findAll() as $module => $local_tasks) {
+      if (!empty($local_tasks)) {
+        foreach ($local_tasks as $name => $info) {
+          if ($missing_keys = array_diff_key($required_keys, array_intersect_key($info, $required_keys))) {
+            throw new PluginException(String::format('Static local task @name is missing @keys', array('@name' => $name, '@keys' => implode(', ', array_keys($missing_keys)))));
+          }
+
+          $info += array('provider' => $module);
+          // Make sure 'appears_on' is an array.
+          $info['title'] = $this->translationManager->translate($info['title']);
+          $this->derivatives[$name] = $info + $base_plugin_definition;
+        }
+      }
+    }
+
+    return $this->derivatives;
+  }
+
+}
diff --git a/core/lib/Drupal/Core/Menu/Plugin/Menu/LocalTask/StaticLocalTask.php b/core/lib/Drupal/Core/Menu/Plugin/Menu/LocalTask/StaticLocalTask.php
new file mode 100644
index 0000000..1d35daf
--- /dev/null
+++ b/core/lib/Drupal/Core/Menu/Plugin/Menu/LocalTask/StaticLocalTask.php
@@ -0,0 +1,21 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\Core\Menu\Plugin\Menu\LocalAction\StaticLocalTask.
+ */
+
+namespace Drupal\Core\Menu\Plugin\Menu\LocalTask;
+
+use Drupal\Core\Menu\LocalTaskBase;
+use Drupal\Core\Annotation\Menu\LocalTask;
+
+/**
+ * @LocalTask(
+ *   id = "local_task_static",
+ *   derivative = "Drupal\Core\Menu\Plugin\Derivative\StaticLocalTaskDeriver"
+ * )
+ */
+class StaticLocalTask extends LocalTaskBase {
+
+}
diff --git a/core/modules/system/lib/Drupal/system/Tests/Menu/LocalTasksTest.php b/core/modules/system/lib/Drupal/system/Tests/Menu/LocalTasksTest.php
index 34034d6..cb64f28 100644
--- a/core/modules/system/lib/Drupal/system/Tests/Menu/LocalTasksTest.php
+++ b/core/modules/system/lib/Drupal/system/Tests/Menu/LocalTasksTest.php
@@ -165,6 +165,7 @@ public function testPluginLocalTask() {
     $this->assertLocalTasks(array(
       'menu-local-task-test/tasks/settings/sub1',
       'menu-local-task-test/tasks/settings/sub2',
+      'menu-local-task-test/tasks/settings/sub3',
     ), 1);
 
     $result = $this->xpath('//ul[contains(@class, "tabs")]//a[contains(@class, "active")]');
@@ -176,6 +177,7 @@ public function testPluginLocalTask() {
     $this->assertLocalTasks(array(
       'menu-local-task-test/tasks/settings/sub1',
       'menu-local-task-test/tasks/settings/sub2',
+      'menu-local-task-test/tasks/settings/sub3',
     ), 1);
 
     $result = $this->xpath('//ul[contains(@class, "tabs")]//a[contains(@class, "active")]');
diff --git a/core/modules/system/tests/modules/menu_test/menu_test.local_tasks.yml b/core/modules/system/tests/modules/menu_test/menu_test.local_tasks.yml
new file mode 100644
index 0000000..f9bbd7c
--- /dev/null
+++ b/core/modules/system/tests/modules/menu_test/menu_test.local_tasks.yml
@@ -0,0 +1,6 @@
+menu_local_task_test_tasks_settings_sub3:
+  route_name: menu_local_task_test_tasks_settings_sub3
+  title: sub3
+  tab_root_id: menu_local_task_test_tasks_view
+  tab_parent_id: menu_local_task_test_tasks_settings
+  weight: 20
diff --git a/core/modules/system/tests/modules/menu_test/menu_test.routing.yml b/core/modules/system/tests/modules/menu_test/menu_test.routing.yml
index 2d701dc..43f008d 100644
--- a/core/modules/system/tests/modules/menu_test/menu_test.routing.yml
+++ b/core/modules/system/tests/modules/menu_test/menu_test.routing.yml
@@ -100,6 +100,13 @@ menu_local_task_test_tasks_settings_sub2:
   requirements:
     _access: 'TRUE'
 
+menu_local_task_test_tasks_settings_sub3:
+  pattern: '/menu-local-task-test/tasks/settings/sub3'
+  defaults:
+    _content: '\Drupal\menu_test\TestControllers::test1'
+  requirements:
+    _access: 'TRUE'
+
 menu_test_optional_placeholder:
   pattern: '/menu-test/optional/{placeholder}'
   defaults:
diff --git a/core/modules/views_ui/lib/Drupal/views_ui/Plugin/Menu/LocalTask/ViewsListTask.php b/core/modules/views_ui/lib/Drupal/views_ui/Plugin/Menu/LocalTask/ViewsListTask.php
deleted file mode 100644
index f1237fc..0000000
--- a/core/modules/views_ui/lib/Drupal/views_ui/Plugin/Menu/LocalTask/ViewsListTask.php
+++ /dev/null
@@ -1,25 +0,0 @@
-<?php
-
-/**
- * @file
- * Contains \Drupal\views_ui\Plugin\Menu\LocalTask\ViewsListTask.
- */
-
-namespace Drupal\views_ui\Plugin\Menu\LocalTask;
-
-use Drupal\Core\Annotation\Translation;
-use Drupal\Core\Menu\LocalTaskBase;
-use Drupal\Core\Annotation\Menu\LocalTask;
-
-
-/**
- * @LocalTask(
- *   id = "views_ui_list_tab",
- *   route_name = "views_ui.list",
- *   title = @Translation("List"),
- *   tab_root_id = "views_ui_list_tab"
- * )
- */
-class ViewsListTask extends LocalTaskBase {
-
-}
diff --git a/core/modules/views_ui/lib/Drupal/views_ui/Plugin/Menu/LocalTask/ViewsSettingsAdvancedTask.php b/core/modules/views_ui/lib/Drupal/views_ui/Plugin/Menu/LocalTask/ViewsSettingsAdvancedTask.php
deleted file mode 100644
index 4ab9b77..0000000
--- a/core/modules/views_ui/lib/Drupal/views_ui/Plugin/Menu/LocalTask/ViewsSettingsAdvancedTask.php
+++ /dev/null
@@ -1,26 +0,0 @@
-<?php
-
-/**
- * @file
- * Contains \Drupal\views_ui\Plugin\Menu\LocalTask\ViewsSettingsAdvancedTas.
- */
-
-namespace Drupal\views_ui\Plugin\Menu\LocalTask;
-
-use Drupal\Core\Annotation\Translation;
-use Drupal\Core\Menu\LocalTaskBase;
-use Drupal\Core\Annotation\Menu\LocalTask;
-
-/**
- * @LocalTask(
- *   id = "views_ui_settings_advanced_tab",
- *   route_name = "views_ui.settings.advanced",
- *   title = @Translation("Advanced"),
- *   tab_root_id = "views_ui_list_tab",
- *   tab_parent_id = "views_ui_settings_tab",
- *   weight = "10"
- * )
- */
-class ViewsSettingsAdvancedTask extends LocalTaskBase {
-
-}
diff --git a/core/modules/views_ui/lib/Drupal/views_ui/Plugin/Menu/LocalTask/ViewsSettingsBasicTask.php b/core/modules/views_ui/lib/Drupal/views_ui/Plugin/Menu/LocalTask/ViewsSettingsBasicTask.php
deleted file mode 100644
index c8d454f..0000000
--- a/core/modules/views_ui/lib/Drupal/views_ui/Plugin/Menu/LocalTask/ViewsSettingsBasicTask.php
+++ /dev/null
@@ -1,25 +0,0 @@
-<?php
-
-/**
- * @file
- * Contains \Drupal\views_ui\Plugin\Menu\LocalTask\ViewsSettingsBasicTask.
- */
-
-namespace Drupal\views_ui\Plugin\Menu\LocalTask;
-
-use Drupal\Core\Annotation\Translation;
-use Drupal\Core\Menu\LocalTaskBase;
-use Drupal\Core\Annotation\Menu\LocalTask;
-
-/**
- * @LocalTask(
- *   id = "views_ui_settings_basic_tab",
- *   route_name = "views_ui.settings.basic",
- *   title = @Translation("Basic"),
- *   tab_root_id = "views_ui_list_tab",
- *   tab_parent_id = "views_ui_settings_tab"
- * )
- */
-class ViewsSettingsBasicTask extends LocalTaskBase {
-
-}
diff --git a/core/modules/views_ui/lib/Drupal/views_ui/Plugin/Menu/LocalTask/ViewsSettingsTask.php b/core/modules/views_ui/lib/Drupal/views_ui/Plugin/Menu/LocalTask/ViewsSettingsTask.php
deleted file mode 100644
index 9dddf80..0000000
--- a/core/modules/views_ui/lib/Drupal/views_ui/Plugin/Menu/LocalTask/ViewsSettingsTask.php
+++ /dev/null
@@ -1,24 +0,0 @@
-<?php
-
-/**
- * @file
- * Contains \Drupal\views_ui\Plugin\Menu\LocalTask\ViewsSettingsTask.
- */
-
-namespace Drupal\views_ui\Plugin\Menu\LocalTask;
-
-use Drupal\Core\Annotation\Translation;
-use Drupal\Core\Menu\LocalTaskBase;
-use Drupal\Core\Annotation\Menu\LocalTask;
-
-/**
- * @LocalTask(
- *   id = "views_ui_settings_tab",
- *   route_name = "views_ui.settings.basic",
- *   title = @Translation("Settings"),
- *   tab_root_id = "views_ui_list_tab"
- * )
- */
-class ViewsSettingsTask extends LocalTaskBase {
-
-}
diff --git a/core/modules/views_ui/views_ui.local_tasks.yml b/core/modules/views_ui/views_ui.local_tasks.yml
new file mode 100644
index 0000000..40ad082
--- /dev/null
+++ b/core/modules/views_ui/views_ui.local_tasks.yml
@@ -0,0 +1,22 @@
+views_ui_settings_tab:
+  route_name: views_ui.settings.basic
+  title: Settings
+  tab_root_id: local_task_static:views_ui_list_tab
+
+views_ui_settings_basic_tab:
+  route_name: views_ui.settings.basic
+  title: Basic
+  tab_root_id: local_task_static:views_ui_list_tab
+  tab_parent_id: local_task_static:views_ui_settings_tab
+
+views_ui_settings_advanced_tab:
+  route_name: views_ui.settings.advanced
+  title: Advanced
+  tab_root_id: local_task_static:views_ui_list_tab
+  tab_parent_id: local_task_static:views_ui_settings_tab
+  weight: 10
+
+views_ui_list_tab:
+  route_name: views_ui.list
+  title: List
+  tab_root_id: local_task_static:views_ui_list_tab
