diff --git a/core/modules/link/link.module b/core/modules/link/link.module
index bfd6ebf..595c151 100644
--- a/core/modules/link/link.module
+++ b/core/modules/link/link.module
@@ -100,20 +100,27 @@ function link_theme() {
   return array(
     'link_formatter_link_separate' => array(
       'variables' => array('title' => NULL, 'url_title' => NULL, 'href' => NULL, 'options' => array()),
+      'template' => 'link-formatter-link-separate',
     ),
   );
 }
 
 /**
  * Formats a link as separate link title and URL elements.
+ *
+ * @param array $vars
+ *   An associative array containing:
+ *   - title: (optional) A descriptive or alternate title for the link, which
+ *     may be different than the actual link text.
+ *   - url_title: The anchor text for the link.
+ *   - href: The link URL.
+ *   - options: (optional) An array of options to pass to l().
  */
-function theme_link_formatter_link_separate($vars) {
-  $output = '';
-  $output .= '<div class="link-item">';
-  if (!empty($vars['title'])) {
-    $output .= '<div class="link-title">' . check_plain($vars['title']) . '</div>';
+function template_preprocess_link_formatter_link_separate(&$variables) {
+  if (!empty($variables['title'])) {
+    $variables['title'] = check_plain($variables['title']);
   }
-  $output .= '<div class="link-url">' . l($vars['url_title'], $vars['href'], $vars['options']) . '</div>';
-  $output .= '</div>';
-  return $output;
+  // @todo Revisit this use of l() after http://drupal.org/node/1922454 is
+  //   resolved.
+  $variables['link'] = l($variables['url_title'], $variables['href'], $variables['options']);
 }
diff --git a/core/modules/link/templates/link-formatter-link-separate.html.twig b/core/modules/link/templates/link-formatter-link-separate.html.twig
new file mode 100644
index 0000000..16b91ed
--- /dev/null
+++ b/core/modules/link/templates/link-formatter-link-separate.html.twig
@@ -0,0 +1,24 @@
+{#
+/**
+ * @file
+ * Default theme implementation of a link with separate title and URL elements.
+ *
+ * Available variables:
+ * - link: The link that has already been formatted by l().
+ * - title: (optional) A descriptive or alternate title for the link, which may
+ *   be different than the actual link text.
+ *
+ * @see template_preprocess()
+ * @see template_preprocess_link_formatter_link_separate()
+ *
+ * @ingroup themeable
+ */
+#}
+{% spaceless %}
+  <div class="link-item">
+    {% if title %}
+      <div class="link-title">{{ title }}</div>
+    {% endif %}
+    <div class="link-url">{{ link }}</div>
+  </div>
+{% endspaceless %}
diff --git a/core/modules/node/tests/modules/node_test/lib/Drupal/node_test/NodeTestStorageController.php b/core/modules/node/tests/modules/node_test/lib/Drupal/node_test/NodeTestStorageController.php
new file mode 100644
index 0000000..3e58980
--- /dev/null
+++ b/core/modules/node/tests/modules/node_test/lib/Drupal/node_test/NodeTestStorageController.php
@@ -0,0 +1,25 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\node_test\NodeTestStorageController.
+ */
+
+namespace Drupal\node_test;
+
+use Drupal\node\NodeStorageController;
+use Drupal\Core\Entity\EntityInterface;
+
+/**
+ * Provides a test storage controller for nodes.
+ */
+class NodeTestStorageController extends NodeStorageController {
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function preSave(EntityInterface $node) {
+    // Allow test nodes to specify their updated ('changed') time.
+  }
+
+}
