diff --git a/core/includes/common.inc b/core/includes/common.inc
index dfd20fa..df43faf 100644
--- a/core/includes/common.inc
+++ b/core/includes/common.inc
@@ -1314,6 +1314,12 @@ function l($text, $path, array $options = array()) {
     'language' => NULL,
   );
 
+  // 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'];
+  }
+
   // Because l() is called very often we statically cache values that require an
   // extra function call.
   static $drupal_static_fast;
diff --git a/core/modules/system/lib/Drupal/system/Tests/Common/UrlTest.php b/core/modules/system/lib/Drupal/system/Tests/Common/UrlTest.php
index 249afd4..d9b9511 100644
--- a/core/modules/system/lib/Drupal/system/Tests/Common/UrlTest.php
+++ b/core/modules/system/lib/Drupal/system/Tests/Common/UrlTest.php
@@ -51,9 +51,32 @@ function testLinkXSS() {
   }
 
   /**
-   * Tests for active class in links produced by l() and #type 'link'.
+   * Tests that default and custom attributes are handled correctly on links.
    */
-  function testLinkActiveClass() {
+  function testLinkAttributes() {
+    // Test that hreflang is added when a link has a known language.
+    $langcode = 'fr';
+    $hreflang_link = array(
+      '#type' => 'link',
+      '#options' => array(
+        'language' => $langcode,
+      ),
+      '#href' => 'http://drupal.org',
+      '#title' => 'bar',
+    );
+
+    // Test that the default hreflang handling for links does not override a
+    // hreflang attribute explicitly set in the render array.
+    $hreflang_override_link = $hreflang_link;
+    $hreflang_override_link['#options']['attributes']['hreflang'] = 'foo';
+
+    $rendered = drupal_render($hreflang_link);
+    $this->assertTrue($this->hasAttribute('hreflang', $rendered, $langcode), format_string('hreflang attribute with value @langcode is present on a rendered link when langcode is provided in the render array.', array('@langcode' => $langcode)));
+
+    $rendered = drupal_render($hreflang_override_link);
+    $this->assertTrue($this->hasAttribute('hreflang', $rendered, 'foo'), format_string('hreflang attribute with value @hreflang is present on a rendered link when @hreflang is provided in the render array.', array('@hreflang' => 'foo')));
+
+    // Test the active class in links produced by l() and #type 'link'.
     $options_no_query = array();
     $options_query = array(
       'query' => array(
@@ -87,16 +110,12 @@ function testLinkActiveClass() {
 
     $links = $this->xpath('//a[@href = :href and not(contains(@class, :class))]', array(':href' => url($path, $options_no_query), ':class' => 'active'));
     $this->assertTrue(isset($links[0]), 'A link generated by l() to the current page without a query string when the current page has a query string is not marked active.');
-  }
 
-  /**
-   * Tests for custom class in links produced by l() and #type 'link'.
-   */
-  function testLinkCustomClass() {
+    // Test adding a custom class in links produced by l() and #type 'link'.
     // Test l().
     $class_l = $this->randomName();
     $link_l = l($this->randomName(), current_path(), array('attributes' => array('class' => array($class_l))));
-    $this->assertTrue($this->hasClass($link_l, $class_l), format_string('Custom class @class is present on link when requested by l()', array('@class' => $class_l)));
+    $this->assertTrue($this->hasAttribute('class', $link_l, $class_l), format_string('Custom class @class is present on link when requested by l()', array('@class' => $class_l)));
 
     // Test #type.
     $class_theme = $this->randomName();
@@ -111,7 +130,7 @@ function testLinkCustomClass() {
       ),
     );
     $link_theme = drupal_render($type_link);
-    $this->assertTrue($this->hasClass($link_theme, $class_theme), format_string('Custom class @class is present on link when requested by #type', array('@class' => $class_theme)));
+    $this->assertTrue($this->hasAttribute('class', $link_theme, $class_theme), format_string('Custom class @class is present on link when requested by #type', array('@class' => $class_theme)));
   }
 
   /**
@@ -156,8 +175,8 @@ function testLinkRenderArrayText() {
    * @return bool
    *   TRUE if the class is found, FALSE otherwise.
    */
-  private function hasClass($link, $class) {
-    return preg_match('|class="([^\"\s]+\s+)*' . $class . '|', $link);
+  private function hasAttribute($attribute, $link, $class) {
+    return preg_match('|' . $attribute . '="([^\"\s]+\s+)*' . $class . '|', $link);
   }
 
   /**
