diff --git a/core/includes/common.inc b/core/includes/common.inc
index 654d849..9593304 100644
--- a/core/includes/common.inc
+++ b/core/includes/common.inc
@@ -1692,6 +1692,7 @@ function datetime_default_format_type() {
  *     path is assumed already to be the correct path alias, and the alias is
  *     not looked up.
  *   - The special string '<front>' generates a link to the site's base URL.
+ *   - The special string '<none>' generates an empty URL.
  *   - If your external URL contains a query (e.g. http://example.com/foo?a=b),
  *     then you can either URL encode the query keys and values yourself and
  *     include them in $path, or use $options['query'] to let this function
@@ -1811,6 +1812,10 @@ function url($path = NULL, array $options = array()) {
   if ($path == '<front>') {
     $path = '';
   }
+  // The special path '<none>' links to nothing.
+  else if ($path == '<none>') {
+    return '';
+  }
   elseif (!empty($path) && !$options['alias']) {
     $langcode = isset($options['language']) && isset($options['language']->langcode) ? $options['language']->langcode : '';
     $alias = drupal_container()->get('path.alias_manager')->getPathAlias($original_path, $langcode);
diff --git a/core/includes/menu.inc b/core/includes/menu.inc
index 6b62bf8..2c3fbe6 100644
--- a/core/includes/menu.inc
+++ b/core/includes/menu.inc
@@ -1591,7 +1591,13 @@ function theme_menu_link(array $variables) {
   if ($element['#below']) {
     $sub_menu = drupal_render($element['#below']);
   }
-  $output = l($element['#title'], $element['#href'], $element['#localized_options']);
+
+  if ($element['#href'] != '<none>') {
+    $output = l($element['#title'], $element['#href'], $element['#localized_options']);
+  }
+  else {
+    $output = '<span class="no-link">' . $element['#title'] . '</span>';
+  }
   return '<li' . new Attribute($element['#attributes']) . '>' . $output . $sub_menu . "</li>\n";
 }
 
diff --git a/core/includes/path.inc b/core/includes/path.inc
index 182c0c8..39cf147 100644
--- a/core/includes/path.inc
+++ b/core/includes/path.inc
@@ -199,7 +199,7 @@ function drupal_valid_path($path, $dynamic_allowed = FALSE) {
   global $menu_admin;
   // We indicate that a menu administrator is running the menu access check.
   $menu_admin = TRUE;
-  if ($path == '<front>' || url_is_external($path)) {
+  if ($path == '<front>' || $path == '<none>' || url_is_external($path)) {
     $item = array('access' => TRUE);
   }
   elseif ($dynamic_allowed && preg_match('/\/\%/', $path)) {
diff --git a/core/includes/theme.inc b/core/includes/theme.inc
index 47c99d9..53ceb96 100644
--- a/core/includes/theme.inc
+++ b/core/includes/theme.inc
@@ -1810,7 +1810,12 @@ function theme_links($variables) {
         }
         else {
           // Pass in $link as $options, they share the same keys.
-          $item = l($link['title'], $link['href'], $link);
+          if ($link['href'] != '<none>') {
+            $item = l($link['title'], $link['href'], $link);
+          }
+          else {
+            $item = '<span class="no-link">' . $link['title'] . '</span>';
+          }
         }
       }
       // Handle title-only text items.
diff --git a/core/modules/menu_link/lib/Drupal/menu_link/MenuLinkFormController.php b/core/modules/menu_link/lib/Drupal/menu_link/MenuLinkFormController.php
index 9506602..845fdd0 100644
--- a/core/modules/menu_link/lib/Drupal/menu_link/MenuLinkFormController.php
+++ b/core/modules/menu_link/lib/Drupal/menu_link/MenuLinkFormController.php
@@ -62,7 +62,7 @@ public function form(array $form, array &$form_state, EntityInterface $menu_link
         '#title' => t('Path'),
         '#maxlength' => 255,
         '#default_value' => $path,
-        '#description' => t('The path for this menu link. This can be an internal Drupal path such as %add-node or an external URL such as %drupal. Enter %front to link to the front page.', array('%front' => '<front>', '%add-node' => 'node/add', '%drupal' => 'http://drupal.org')),
+        '#description' => t('The path for this menu link. This can be an internal Drupal path such as %add-node or an external URL such as %drupal. Enter %front to link to the front page. Enter %none for unlinked text.', array('%front' => '<front>', '%add-node' => 'node/add', '%drupal' => 'http://drupal.org', '%none' => '<none>')),
         '#required' => TRUE,
       );
     }
diff --git a/core/modules/menu_link/lib/Drupal/menu_link/MenuLinkStorageController.php b/core/modules/menu_link/lib/Drupal/menu_link/MenuLinkStorageController.php
index dd4ffcc..22a9506 100644
--- a/core/modules/menu_link/lib/Drupal/menu_link/MenuLinkStorageController.php
+++ b/core/modules/menu_link/lib/Drupal/menu_link/MenuLinkStorageController.php
@@ -160,9 +160,9 @@ public function save(EntityInterface $entity) {
    * Overrides DatabaseStorageController::preSave().
    */
   protected function preSave(EntityInterface $entity) {
-    // This is the easiest way to handle the unique internal path '<front>',
+    // This is the easiest way to handle unique paths '<front>' and '<none>',
     // since a path marked as external does not need to match a router path.
-    $entity->external = (url_is_external($entity->link_path) || $entity->link_path == '<front>') ? 1 : 0;
+    $entity->external = (url_is_external($entity->link_path) || $entity->link_path == '<front>' || $entity->link_path == '<none>') ? 1 : 0;
 
     // Try to find a parent link. If found, assign it and derive its menu.
     $parent_candidates = !empty($entity->parentCandidates) ? $entity->parentCandidates : array();
diff --git a/core/modules/system/lib/Drupal/system/Tests/Menu/EmptyLinkPathTest.php b/core/modules/system/lib/Drupal/system/Tests/Menu/EmptyLinkPathTest.php
new file mode 100644
index 0000000..a00792e
--- /dev/null
+++ b/core/modules/system/lib/Drupal/system/Tests/Menu/EmptyLinkPathTest.php
@@ -0,0 +1,70 @@
+<?php
+
+/**
+ * @file
+ * Definition of Drupal\system\Tests\Menu\EmptyLinkPathTest.
+ */
+
+namespace Drupal\system\Tests\Menu;
+
+use Drupal\simpletest\WebTestBase;
+
+/**
+ * Tests for menu links.
+ */
+class EmptyLinkPathTest extends WebTestBase {
+  public static function getInfo() {
+    return array(
+      'name' => 'Menu link with empty path',
+      'description' => 'Test handling of empty link path.',
+      'group' => 'Menu',
+    );
+  }
+
+  /**
+   * Test automatic reparenting of menu links.
+   */
+  function testEmptyLinkPath($module = 'menu_test') {
+    $path = '<none>';
+
+    // Verify that the path is valid.
+    $path_is_valid = drupal_valid_path($path);
+    $this->assertTrue($path_is_valid, '&lt;none> is a valid path.');
+
+    // Verify that url return an empty string.
+    $link = url($path);
+    $this->assertEqual($link, '', 'Url &lt;none> return an empty string.');
+
+    // Menu link without a path return a span.
+    $link_title = 'Empty path';
+    $link = array(
+      '#title' => $link_title,
+      '#href' => $path,
+      '#below' => array(),
+      '#localized_options' => array(),
+      '#attributes' => array()
+    );
+    $menu_link = array(
+      'element' => $link
+    );
+    $menu_link_string = theme_menu_link($menu_link);
+    $expected_link_string = '<span class="no-link">' . $link_title . '</span>';
+    $contains_link = (strpos($menu_link_string, $expected_link_string) !== FALSE);
+    $this->assertTrue($contains_link, 'Menu link without path return a span.');
+
+    // Verify that theme_links() also accept <none> path.
+    $links_string = theme_links(array(
+      'links' => array(
+        array(
+          'title' => $link_title,
+          'href' => $path
+        )
+      ),
+      'attributes' => array(),
+      'heading' => array()
+    ));
+    $contains_link = (strpos($links_string, $expected_link_string) !== FALSE);
+    $this->assertTrue($contains_link, 'Function theme_links() accept &lt;none> path.');
+  }
+
+}
