diff --git a/core/includes/common.inc b/core/includes/common.inc
index fde8b06..d231a7f 100644
--- a/core/includes/common.inc
+++ b/core/includes/common.inc
@@ -749,65 +749,7 @@ function drupal_http_header_attributes(array $attributes = array()) {
  * @see system_page_build()
  */
 function l($text, $path, array $options = array()) {
-  // Start building a structured representation of our link to be altered later.
-  $variables = array(
-    'text' => is_array($text) ? drupal_render($text) : $text,
-    'path' => $path,
-    'options' => $options,
-  );
-
-  // Merge in default options.
-  $variables['options'] += array(
-    'attributes' => array(),
-    'query' => array(),
-    'html' => FALSE,
-    'language' => NULL,
-    'set_active_class' => FALSE,
-  );
-
-  // Add a hreflang attribute if we know the language of this link's url and
-  // hreflang has not already been set.
-  if (!empty($variables['options']['language']) && !isset($variables['options']['attributes']['hreflang'])) {
-    $variables['options']['attributes']['hreflang'] = $variables['options']['language']->id;
-  }
-
-  // Set the "active" class if the 'set_active_class' option is not empty.
-  if (!empty($variables['options']['set_active_class'])) {
-    // Add a "data-drupal-link-query" attribute to let the drupal.active-link
-    // library know the query in a standardized manner.
-    if (!empty($variables['options']['query'])) {
-      $query = $variables['options']['query'];
-      ksort($query);
-      $variables['options']['attributes']['data-drupal-link-query'] = Json::encode($query);
-    }
-
-    // Add a "data-drupal-link-system-path" attribute to let the
-    // drupal.active-link library know the path in a standardized manner.
-    if (!isset($variables['options']['attributes']['data-drupal-link-system-path'])) {
-      $variables['options']['attributes']['data-drupal-link-system-path'] = \Drupal::service('path.alias_manager')->getPathByAlias($path);
-    }
-  }
-
-  // Remove all HTML and PHP tags from a tooltip, calling expensive strip_tags()
-  // only when a quick strpos() gives suspicion tags are present.
-  if (isset($variables['options']['attributes']['title']) && strpos($variables['options']['attributes']['title'], '<') !== FALSE) {
-    $variables['options']['attributes']['title'] = strip_tags($variables['options']['attributes']['title']);
-  }
-
-  // Allow other modules to modify the structure of the link.
-  \Drupal::moduleHandler()->alter('link', $variables);
-
-  // Move attributes out of options. url() doesn't need them.
-  $attributes = new Attribute($variables['options']['attributes']);
-  unset($variables['options']['attributes']);
-
-  // The result of url() is a plain-text URL. Because we are using it here
-  // in an HTML argument context, we need to encode it properly.
-  $url = String::checkPlain(url($variables['path'], $variables['options']));
-
-  // Sanitize the link text if necessary.
-  $text = $variables['options']['html'] ? $variables['text'] : String::checkPlain($variables['text']);
-  return SafeMarkup::set('<a href="' . $url . '"' . $attributes . '>' . $text . '</a>');
+  return \Drupal::linkGenerator()->generateFromPath($text, $path, $options);
 }
 
 /**
diff --git a/core/lib/Drupal/Core/Url.php b/core/lib/Drupal/Core/Url.php
index d97f017..76ec4b5 100644
--- a/core/lib/Drupal/Core/Url.php
+++ b/core/lib/Drupal/Core/Url.php
@@ -115,6 +115,8 @@ public function __construct($route_name, $route_parameters = array(), $options =
    *
    * @param string $path
    *   A path (e.g. 'node/1', 'http://drupal.org').
+   * @param array $options
+   *   (optional) The options array, see __construct defaults to an empty array.
    *
    * @return static
    *   An Url object. Warning: the object is created even if the current user
@@ -123,19 +125,20 @@ public function __construct($route_name, $route_parameters = array(), $options =
    * @throws \Drupal\Core\Routing\MatchingRouteNotFoundException
    *   Thrown when the path cannot be matched.
    */
-  public static function createFromPath($path) {
+  public static function createFromPath($path, array $options = array()) {
     if (UrlHelper::isExternal($path)) {
-      $url = new static($path);
+      $url = new static($path, array(), $options);
       $url->setExternal();
       return $url;
     }
 
     // Special case the front page route.
     if ($path == '<front>') {
-      return new static($path);
+      return new static($path, [], $options);
     }
     else {
-      return static::createFromRequest(Request::create("/$path"));
+      $url = static::createFromRequest(Request::create("/$path"));
+      return $url->setOptions($options);
     }
   }
 
diff --git a/core/lib/Drupal/Core/Utility/LinkGenerator.php b/core/lib/Drupal/Core/Utility/LinkGenerator.php
index f8660ab..7a51da7 100644
--- a/core/lib/Drupal/Core/Utility/LinkGenerator.php
+++ b/core/lib/Drupal/Core/Utility/LinkGenerator.php
@@ -13,6 +13,7 @@
 use Drupal\Core\Extension\ModuleHandlerInterface;
 use Drupal\Core\Link;
 use Drupal\Core\Path\AliasManagerInterface;
+use Drupal\Core\Routing\MatchingRouteNotFoundException;
 use Drupal\Core\Routing\UrlGeneratorInterface;
 use Drupal\Core\Template\Attribute;
 use Drupal\Core\Url;
@@ -145,4 +146,17 @@ public function generate($text, $route_name, array $parameters = array(), array
     return $this->generateFromUrl($text, $url);
   }
 
+  /**
+   * {@inheritdoc}
+   */
+  public function generateFromPath($text, $path, array $options = array()) {
+    try {
+      $url = Url::createFromPath($path, $options);
+      return $this->generateFromUrl($text, $url);
+    }
+    catch (MatchingRouteNotFoundException $e) {
+      return "";
+    }
+  }
+
 }
diff --git a/core/lib/Drupal/Core/Utility/LinkGeneratorInterface.php b/core/lib/Drupal/Core/Utility/LinkGeneratorInterface.php
index edce761..6744318 100644
--- a/core/lib/Drupal/Core/Utility/LinkGeneratorInterface.php
+++ b/core/lib/Drupal/Core/Utility/LinkGeneratorInterface.php
@@ -104,4 +104,24 @@ public function generateFromUrl($text, Url $url);
    */
   public function generateFromLink(Link $link);
 
+  /**
+   * Renders a link to a path.
+   *
+   * @param string $text
+   *   The link text for the anchor tag as a translated string.
+   * @param string $path
+   *   The internal path or external URL being linked to, such as "node/34" or
+   *   "http://example.com/foo". After the url() function is called to construct
+   *   the URL from $path and $options, the resulting URL is passed through
+   *   \Drupal\Component\Utility\String::checkPlain() before it is inserted into
+   *   the HTML anchor tag, to ensure well-formed HTML. See url() for more
+   *   information and notes.
+   * @param array $options
+   *   (optional) The options for the link, defaults to an empty array.
+   *
+   * @return string
+   *   An HTML string containing a link to the given path.
+   */
+  public function generateFromPath($text, $path, array $options = array());
+
 }
diff --git a/core/tests/Drupal/Tests/Core/UrlTest.php b/core/tests/Drupal/Tests/Core/UrlTest.php
index 133a73c..197dc12 100644
--- a/core/tests/Drupal/Tests/Core/UrlTest.php
+++ b/core/tests/Drupal/Tests/Core/UrlTest.php
@@ -152,6 +152,24 @@ public function testCreateFromPathInvalid() {
   }
 
   /**
+   * Tests the createFromPath method with options.
+   *
+   * @covers ::createFromPath
+   */
+  public function testCreateFromPathWithOptions() {
+    $url = Url::createFromPath('<front>', array('fragment' => 'test'));
+    $this->assertSame('test', $url->getOption('fragment'));
+  }
+
+  /**
+   * Tests the createFromPath method with an external path.
+   */
+  public function testCreateFromPathWithExternalPath() {
+    $url = Url::createFromPath('https://example.com', array('fragment' => 'test'));
+    $this->assertSame('test', $url->getOption('fragment'));
+  }
+
+  /**
    * Tests the createFromRequest method.
    *
    * @covers ::createFromRequest()
diff --git a/core/tests/Drupal/Tests/Core/Utility/LinkGeneratorTest.php b/core/tests/Drupal/Tests/Core/Utility/LinkGeneratorTest.php
index 7926b2f..11d573e 100644
--- a/core/tests/Drupal/Tests/Core/Utility/LinkGeneratorTest.php
+++ b/core/tests/Drupal/Tests/Core/Utility/LinkGeneratorTest.php
@@ -460,6 +460,15 @@ public function testGenerateActive() {
     ), $result);
   }
 
+  /**
+   * Tests generate a link from path.
+   *
+   * @covers ::generateFromPath
+   * @covers ::generateFromUrl
+   */
+  public function testGenerateFromPath() {
+  }
+
 }
 
 }
