diff --git a/core/lib/Drupal/Core/CoreServiceProvider.php b/core/lib/Drupal/Core/CoreServiceProvider.php
index a7f5ef4..eb8ce9b 100644
--- a/core/lib/Drupal/Core/CoreServiceProvider.php
+++ b/core/lib/Drupal/Core/CoreServiceProvider.php
@@ -81,6 +81,11 @@ public static function registerTwig(ContainerBuilder $container) {
       ->addArgument(DRUPAL_ROOT);
     $container->setAlias('twig.loader', 'twig.loader.filesystem');
 
+    $twig_extension = new Definition('Drupal\Core\Template\TwigExtension');
+    // When in the installer these services are not yet available.
+    if (!drupal_installation_attempted()) {
+      $twig_extension->addMethodCall('setGenerators', array(new Reference('url_generator')));
+    }
     $container->register('twig', 'Drupal\Core\Template\TwigEnvironment')
       ->addArgument(new Reference('twig.loader'))
       ->addArgument(array(
@@ -96,7 +101,7 @@ public static function registerTwig(ContainerBuilder $container) {
       ))
       ->addArgument(new Reference('module_handler'))
       ->addArgument(new Reference('theme_handler'))
-      ->addMethodCall('addExtension', array(new Definition('Drupal\Core\Template\TwigExtension')))
+      ->addMethodCall('addExtension', array($twig_extension))
       // @todo Figure out what to do about debugging functions.
       // @see http://drupal.org/node/1804998
       ->addMethodCall('addExtension', array(new Definition('Twig_Extension_Debug')))
diff --git a/core/lib/Drupal/Core/Template/TwigExtension.php b/core/lib/Drupal/Core/Template/TwigExtension.php
index 69e0bb3..47e445b 100644
--- a/core/lib/Drupal/Core/Template/TwigExtension.php
+++ b/core/lib/Drupal/Core/Template/TwigExtension.php
@@ -12,6 +12,8 @@
 
 namespace Drupal\Core\Template;
 
+use Drupal\Core\Routing\UrlGeneratorInterface;
+
 /**
  * A class providing Drupal Twig extensions.
  *
@@ -22,13 +24,34 @@
 class TwigExtension extends \Twig_Extension {
 
   /**
+   * The URL generator.
+   *
+   * @var \Drupal\Core\Routing\UrlGeneratorInterface
+   */
+  protected $urlGenerator;
+
+  /**
+   * Constructs \Drupal\Core\Template\TwigExtension.
+   *
+   * @param \Drupal\Core\Routing\UrlGeneratorInterface $url_generator
+   *   The URL generator.
+   */
+  public function setGenerators(UrlGeneratorInterface $url_generator) {
+    $this->urlGenerator = $url_generator;
+  }
+
+  /**
    * {@inheritdoc}
    */
   public function getFunctions() {
     return array(
-      new \Twig_SimpleFunction('url', 'url'),
       // This function will receive a renderable array, if an array is detected.
       new \Twig_SimpleFunction('render_var', 'twig_render_var'),
+      // The url and path function are defined in close parallel to those found
+      // in \Symfony\Bridge\Twig\Extension\RoutingExtension
+      'url' => new \Twig_SimpleFunction('url', array($this, 'getUrl'), array('is_safe_callback' => array($this, 'isUrlGenerationSafe'))),
+      'path' => new \Twig_SimpleFunction('path', array($this, 'getPath'), array('is_safe_callback' => array($this, 'isUrlGenerationSafe'))),
+      'url_from_path' => new \Twig_SimpleFunction('url_from_path', array($this, 'getUrlFromPath'), array('is_safe_callback' => array($this, 'isUrlGenerationSafe'))),
     );
   }
 
@@ -88,4 +111,101 @@ public function getName() {
     return 'drupal_core';
   }
 
+  /**
+   * Generates a URL path given a route name and parameters.
+   *
+   * @param $name
+   *   The name of the route.
+   * @param array $parameters
+   *   An associative array of route parameters names and values.
+   * @param array $options
+   *   (optional) An associative array of additional options. The 'absolute'
+   *   option is forced to be FALSE.
+   *   @see \Drupal\Core\Routing\UrlGeneratorInterface::generateFromRoute().
+   *
+   * @return string
+   *   The generated URL path (relative URL) for the given route.
+   */
+  public function getPath($name, $parameters = array(), $options = array()) {
+    $options['absolute'] = FALSE;
+    return $this->urlGenerator->generateFromRoute($name, $parameters, $options);
+  }
+
+  /**
+   * Generates an absolute URL given a route name and parameters.
+   *
+   * @param $name
+   *   The name of the route.
+   * @param array $parameters
+   *   An associative array of route parameter names and values.
+   * @param array $options
+   *   (optional) An associative array of additional options. The 'absolute'
+   *   option is forced to be TRUE.
+   *
+   * @return string
+   *   The generated absolute URL for the given route.
+   *
+   * @todo Add an option for scheme-relative URLs.
+   */
+  public function getUrl($name, $parameters = array(), $options = array()) {
+    $options['absolute'] = TRUE;
+    return $this->urlGenerator->generateFromRoute($name, $parameters, $options);
+  }
+
+  /**
+   * Generates an absolute URL given a path.
+   *
+   * @param string $path
+   *   The path.
+   * @param array $options
+   *   (optional) An associative array of additional options. The 'absolute'
+   *   option is forced to be TRUE.
+   *
+   * @return string
+   *   The generated absolute URL for the given path.
+   */
+  public function getUrlFromPath($path, $options = array()) {
+    $options['absolute'] = TRUE;
+    return $this->urlGenerator->generateFromPath($path, $options);
+  }
+
+  /**
+   * Determines at compile time whether the generated URL will be safe.
+   *
+   * Saves the unneeded automatic escaping for performance reasons.
+   *
+   * The URL generation process percent encodes non-alphanumeric characters.
+   * Thus, the only character within an URL that must be escaped in HTML is the
+   * ampersand ("&") which separates query params. Thus we cannot mark
+   * the generated URL as always safe, but only when we are sure there won't be
+   * multiple query params. This is the case when there are none or only one
+   * constant parameter given. E.g. we know beforehand this will not need to
+   * be escaped:
+   * - path('route')
+   * - path('route', {'param': 'value'})
+   * But the following may need to be escaped:
+   * - path('route', var)
+   * - path('route', {'param': ['val1', 'val2'] }) // a sub-array
+   * - path('route', {'param1': 'value1', 'param2': 'value2'})
+   * If param1 and param2 reference placeholders in the route, it would not
+   * need to be escaped, but we don't know that in advance.
+   *
+   * @param \Twig_Node $args_node
+   *   The arguments of the path/url functions.
+   *
+   * @return array
+   *   An array with the contexts the URL is safe
+   */
+  public function isUrlGenerationSafe(\Twig_Node $args_node) {
+    // Support named arguments.
+    $parameter_node = $args_node->hasNode('parameters') ? $args_node->getNode('parameters') : ($args_node->hasNode(1) ? $args_node->getNode(1) : NULL);
+
+    if (!isset($parameter_node) || $parameter_node instanceof \Twig_Node_Expression_Array && count($parameter_node) <= 2 &&
+        (!$parameter_node->hasNode(1) || $parameter_node->getNode(1) instanceof \Twig_Node_Expression_Constant)) {
+      return array('html');
+    }
+
+    return array();
+  }
+
 }
diff --git a/core/modules/system/src/Tests/Theme/EngineTwigTest.php b/core/modules/system/src/Tests/Theme/EngineTwigTest.php
index 2e89f47..d295182 100644
--- a/core/modules/system/src/Tests/Theme/EngineTwigTest.php
+++ b/core/modules/system/src/Tests/Theme/EngineTwigTest.php
@@ -41,4 +41,27 @@ function testTwigVariableDataTypes() {
     }
   }
 
+  /**
+   * Tests the url and url_generate Twig function.
+   */
+  public function testTwigUrlGenerator() {
+    $this->drupalGet('twig-theme-test/url-generator');
+    // Find the absolute URL of the current site.
+    $url_generator = $this->container->get('url_generator');
+    $link_generator = $this->container->get('link_generator');
+    $expected = array(
+      'path (as route) not absolute: ' . $url_generator->generateFromRoute('user.register'),
+      'url (as route) absolute: ' . $url_generator->generateFromRoute('user.register', array(), array('absolute' => TRUE)),
+      'path (as route) not absolute with fragment: ' . $url_generator->generateFromRoute('user.register', array(), array('fragment' => 'bottom')),
+      'url (as route) absolute despite option: ' . $url_generator->generateFromRoute('user.register', array(), array('absolute' => TRUE)),
+      'url (as route) absolute with fragment: ' . $url_generator->generateFromRoute('user.register', array(), array('absolute' => TRUE, 'fragment' => 'bottom')),
+    );
+    // Make sure we got something.
+    $content = $this->drupalGetContent();
+    $this->assertFalse(empty($content), 'Page content is not empty');
+    foreach ($expected as $string) {
+      $this->assertRaw('<div>' . $string . '</div>');
+    }
+  }
+
 }
diff --git a/core/modules/system/templates/tablesort-indicator.html.twig b/core/modules/system/templates/tablesort-indicator.html.twig
index 1f0eb9d..ab4e2c2 100644
--- a/core/modules/system/templates/tablesort-indicator.html.twig
+++ b/core/modules/system/templates/tablesort-indicator.html.twig
@@ -10,7 +10,7 @@
  */
 #}
 {% if style == 'asc' -%}
-  <img src="{{ url('core/misc/arrow-asc.png') }}" width="13" height="13" alt="{{ 'sort ascending'|t }}" title="{{ 'sort ascending'|t }}" />
+  <img src="{{ url_from_path('core/misc/arrow-asc.png') }}" width="13" height="13" alt="{{ 'sort ascending'|t }}" title="{{ 'sort ascending'|t }}" />
 {% else -%}
-  <img src="{{ url('core/misc/arrow-desc.png') }}" width="13" height="13" alt="{{ 'sort descending'|t }}" title="{{ 'sort descending'|t }}" />
+  <img src="{{ url_from_path('core/misc/arrow-desc.png') }}" width="13" height="13" alt="{{ 'sort descending'|t }}" title="{{ 'sort descending'|t }}" />
 {% endif %}
diff --git a/core/modules/system/tests/modules/twig_theme_test/src/TwigThemeTestController.php b/core/modules/system/tests/modules/twig_theme_test/src/TwigThemeTestController.php
index 45654ea..d454e5f 100644
--- a/core/modules/system/tests/modules/twig_theme_test/src/TwigThemeTestController.php
+++ b/core/modules/system/tests/modules/twig_theme_test/src/TwigThemeTestController.php
@@ -28,4 +28,13 @@ public function transBlockRender() {
     );
   }
 
+  /**
+   * Renders for testing url_generator functions in a Twig template.
+   */
+  public function urlGeneratorRender() {
+    return array(
+      '#theme' => 'twig_theme_test_url_generator',
+    );
+  }
+
 }
diff --git a/core/modules/system/tests/modules/twig_theme_test/templates/twig_theme_test.url_generator.html.twig b/core/modules/system/tests/modules/twig_theme_test/templates/twig_theme_test.url_generator.html.twig
new file mode 100644
index 0000000..131a612
--- /dev/null
+++ b/core/modules/system/tests/modules/twig_theme_test/templates/twig_theme_test.url_generator.html.twig
@@ -0,0 +1,7 @@
+{# Test the url and path twig functions #}
+<div>path (as route) not absolute: {{ path('user.register') }}</div>
+<div>url (as route) absolute: {{ url('user.register') }}</div>
+
+<div>path (as route) not absolute with fragment: {{ path('user.register', {}, {'fragment': 'bottom' }) }}</div>
+<div>url (as route) absolute despite option: {{ url('user.register', {}, {'absolute': false }) }}</div>
+<div>url (as route) absolute with fragment: {{ url('user.register', {}, {'fragment': 'bottom' }) }}</div>
diff --git a/core/modules/system/tests/modules/twig_theme_test/twig_theme_test.module b/core/modules/system/tests/modules/twig_theme_test/twig_theme_test.module
index 5874cca..0497c7b 100644
--- a/core/modules/system/tests/modules/twig_theme_test/twig_theme_test.module
+++ b/core/modules/system/tests/modules/twig_theme_test/twig_theme_test.module
@@ -23,6 +23,10 @@ function twig_theme_test_theme($existing, $type, $theme, $path) {
     'variables' => array('script' => ''),
     'template' => 'twig-raw-test',
   );
+  $items['twig_theme_test_url_generator'] = array(
+    'variables' => array(),
+    'template' => 'twig_theme_test.url_generator',
+  );
   return $items;
 }
 
diff --git a/core/modules/system/tests/modules/twig_theme_test/twig_theme_test.routing.yml b/core/modules/system/tests/modules/twig_theme_test/twig_theme_test.routing.yml
index 96befd4..75b9bbb 100644
--- a/core/modules/system/tests/modules/twig_theme_test/twig_theme_test.routing.yml
+++ b/core/modules/system/tests/modules/twig_theme_test/twig_theme_test.routing.yml
@@ -11,3 +11,10 @@ twig_theme_test.trans:
     _content: '\Drupal\twig_theme_test\TwigThemeTestController::transBlockRender'
   requirements:
     _access: 'TRUE'
+
+twig_theme_test_url_generator:
+  path: '/twig-theme-test/url-generator'
+  defaults:
+    _content: '\Drupal\twig_theme_test\TwigThemeTestController::urlGeneratorRender'
+  requirements:
+    _access: 'TRUE'
diff --git a/core/scripts/run-tests.sh b/core/scripts/run-tests.sh
index 88ba503..af935b9 100755
--- a/core/scripts/run-tests.sh
+++ b/core/scripts/run-tests.sh
@@ -336,6 +336,7 @@ function simpletest_script_init() {
   }
 
   $_SERVER['HTTP_HOST'] = $host;
+  $_SERVER['SERVER_PORT'] = isset($parsed_url['port']) ? $parsed_url['port'] : 80;
   $_SERVER['REMOTE_ADDR'] = '127.0.0.1';
   $_SERVER['SERVER_ADDR'] = '127.0.0.1';
   $_SERVER['SERVER_PORT'] = $port;
