diff --git a/core/core.services.yml b/core/core.services.yml
index e1ef8d2..8d7169c 100644
--- a/core/core.services.yml
+++ b/core/core.services.yml
@@ -567,7 +567,7 @@ services:
     public: false
   controller_resolver:
     class: Drupal\Core\Controller\ControllerResolver
-    arguments: ['@class_resolver']
+    arguments: ['@psr7.http_message_factory', '@class_resolver']
   class_resolver:
     class: Drupal\Core\DependencyInjection\ClassResolver
     calls:
diff --git a/core/lib/Drupal/Core/Controller/ControllerResolver.php b/core/lib/Drupal/Core/Controller/ControllerResolver.php
index bf58aff..3c8fd66 100644
--- a/core/lib/Drupal/Core/Controller/ControllerResolver.php
+++ b/core/lib/Drupal/Core/Controller/ControllerResolver.php
@@ -12,6 +12,8 @@
 use Symfony\Component\HttpFoundation\Request;
 use Symfony\Component\HttpKernel\Controller\ControllerResolver as BaseControllerResolver;
 use Drupal\Core\DependencyInjection\ClassResolverInterface;
+use Symfony\Bridge\PsrHttpMessage\HttpMessageFactoryInterface;
+
 
 /**
  * ControllerResolver to enhance controllers beyond Symfony's basic handling.
@@ -38,12 +40,20 @@ class ControllerResolver extends BaseControllerResolver implements ControllerRes
   protected $classResolver;
 
   /**
+   * The psr7 converter.
+   *
+   * @var \Symfony\Bridge\PsrHttpMessage\HttpMessageFactoryInterface;
+   */
+  protected $httpMessageFactory;
+
+  /**
    * Constructs a new ControllerResolver.
    *
    * @param \Drupal\Core\DependencyInjection\ClassResolverInterface $class_resolver
    *   The class resolver.
    */
-  public function __construct(ClassResolverInterface $class_resolver) {
+  public function __construct(HttpMessageFactoryInterface $http_message_factory, ClassResolverInterface $class_resolver) {
+    $this->httpMessageFactory = $http_message_factory;
     $this->classResolver = $class_resolver;
   }
 
@@ -60,7 +70,7 @@ public function getControllerFromDefinition($controller, $path = '') {
         return $controller;
       }
       elseif (method_exists($controller, '__invoke')) {
-        return new $controller;
+        return new $controller();
       }
     }
 
@@ -94,10 +104,10 @@ public function getController(Request $request) {
    *   A PHP callable.
    *
    * @throws \LogicException
-   *   If the controller cannot be parsed
+   *   If the controller cannot be parsed.
    *
    * @throws \InvalidArgumentException
-   *   If the controller class does not exist
+   *   If the controller class does not exist.
    */
   protected function createController($controller) {
     // Controller in the service:method notation.
@@ -115,7 +125,7 @@ protected function createController($controller) {
 
     $controller = $this->classResolver->getInstanceFromDefinition($class_or_service);
 
-    return array($controller, $method);
+    return [$controller, $method];
   }
 
   /**
@@ -124,7 +134,7 @@ protected function createController($controller) {
   protected function doGetArguments(Request $request, $controller, array $parameters) {
     $attributes = $request->attributes->all();
     $raw_parameters = $request->attributes->has('_raw_variables') ? $request->attributes->get('_raw_variables') : [];
-    $arguments = array();
+    $arguments = [];
     foreach ($parameters as $param) {
       if (array_key_exists($param->name, $attributes)) {
         $arguments[] = $attributes[$param->name];
@@ -135,6 +145,9 @@ protected function doGetArguments(Request $request, $controller, array $paramete
       elseif ($param->getClass() && $param->getClass()->isInstance($request)) {
         $arguments[] = $request;
       }
+      elseif ($param->getClass() && $param->getClass()->name === 'Psr\Http\Message\ServerRequestInterface') {
+        $arguments[] = $this->httpMessageFactory->createRequest($request);
+      }
       elseif ($param->getClass() && ($param->getClass()->name == 'Drupal\Core\Routing\RouteMatchInterface' || is_subclass_of($param->getClass()->name, 'Drupal\Core\Routing\RouteMatchInterface'))) {
         $arguments[] = RouteMatch::createFromRequest($request);
       }
diff --git a/core/tests/Drupal/Tests/Core/Controller/ControllerResolverTest.php b/core/tests/Drupal/Tests/Core/Controller/ControllerResolverTest.php
index d015a31..ddd0b09 100644
--- a/core/tests/Drupal/Tests/Core/Controller/ControllerResolverTest.php
+++ b/core/tests/Drupal/Tests/Core/Controller/ControllerResolverTest.php
@@ -19,6 +19,8 @@
 use Symfony\Component\DependencyInjection\ContainerInterface;
 use Symfony\Component\DependencyInjection\ParameterBag\ParameterBag;
 use Symfony\Component\HttpFoundation\Request;
+use Symfony\Bridge\PsrHttpMessage\Factory\DiactorosFactory;
+use Psr\Http\Message\ServerRequestInterface;
 
 /**
  * @coversDefaultClass \Drupal\Core\Controller\ControllerResolver
@@ -41,6 +43,13 @@ class ControllerResolverTest extends UnitTestCase {
   protected $container;
 
   /**
+   * The psr7 converter.
+   *
+   * @var \Symfony\Bridge\PsrHttpMessage\HttpMessageFactoryInterface;
+   */
+  protected $httpMessageFactory;
+
+  /**
    * {@inheritdoc}
    */
   protected function setUp() {
@@ -49,7 +58,8 @@ protected function setUp() {
     $this->container = new ContainerBuilder();
     $class_resolver = new ClassResolver();
     $class_resolver->setContainer($this->container);
-    $this->controllerResolver = new ControllerResolver($class_resolver);
+    $this->httpMessageFactory = new DiactorosFactory();
+    $this->controllerResolver = new ControllerResolver($this->httpMessageFactory, $class_resolver);
   }
 
   /**
@@ -61,22 +71,23 @@ protected function setUp() {
    * @see \Drupal\Core\Controller\ControllerResolver::doGetArguments()
    */
   public function testGetArguments() {
-    $controller = function(EntityInterface $entity, $user, RouteMatchInterface $route_match) {
+    $controller = function(EntityInterface $entity, $user, RouteMatchInterface $route_match, ServerRequestInterface $psr_7) {
     };
     $mock_entity = $this->getMockBuilder('Drupal\Core\Entity\Entity')
       ->disableOriginalConstructor()
       ->getMock();
     $mock_account = $this->getMock('Drupal\Core\Session\AccountInterface');
-    $request = new Request(array(), array(), array(
+    $request = new Request([], [], [
       'entity' => $mock_entity,
       'user' => $mock_account,
-      '_raw_variables' => new ParameterBag(array('entity' => 1, 'user' => 1)),
-    ));
+      '_raw_variables' => new ParameterBag(['entity' => 1, 'user' => 1]),
+    ], [], [], ['HTTP_HOST' => 'drupal.org']);
     $arguments = $this->controllerResolver->getArguments($request, $controller);
 
     $this->assertEquals($mock_entity, $arguments[0]);
     $this->assertEquals($mock_account, $arguments[1]);
     $this->assertEquals(RouteMatch::createFromRequest($request), $arguments[2], 'Ensure that the route match object is passed along as well');
+    $this->assertInstanceOf('Psr\Http\Message\ServerRequestInterface', $arguments[3], 'Ensure that the psr7 object is passed along as well');
   }
 
   /**
@@ -94,16 +105,28 @@ public function testCreateController($controller, $class, $output) {
    * Provides test data for testCreateController().
    */
   public function providerTestCreateController() {
-    return array(
+    return [
       // Tests class::method.
-      array('Drupal\Tests\Core\Controller\MockController::getResult', 'Drupal\Tests\Core\Controller\MockController', 'This is a regular controller.'),
+      ['Drupal\Tests\Core\Controller\MockController::getResult',
+       'Drupal\Tests\Core\Controller\MockController',
+        'This is a regular controller.'
+      ],
       // Tests service:method.
-      array('some_service:getResult', 'Drupal\Tests\Core\Controller\MockController', 'This is a regular controller.'),
+      ['some_service:getResult',
+       'Drupal\Tests\Core\Controller\MockController',
+       'This is a regular controller.'
+      ],
       // Tests a class with injection.
-      array('Drupal\Tests\Core\Controller\MockContainerInjection::getResult', 'Drupal\Tests\Core\Controller\MockContainerInjection', 'This used injection.'),
+      ['Drupal\Tests\Core\Controller\MockContainerInjection::getResult',
+       'Drupal\Tests\Core\Controller\MockContainerInjection',
+       'This used injection.'
+      ],
       // Tests a ContainerAware class.
-      array('Drupal\Tests\Core\Controller\MockContainerAware::getResult', 'Drupal\Tests\Core\Controller\MockContainerAware', 'This is container aware.'),
-    );
+      ['Drupal\Tests\Core\Controller\MockContainerAware::getResult',
+       'Drupal\Tests\Core\Controller\MockContainerAware',
+       'This is container aware.'
+      ],
+    ];
   }
 
   /**
@@ -130,7 +153,7 @@ public function testCreateControllerInvalidName() {
    * @dataProvider providerTestGetController
    */
   public function testGetController($attributes, $class, $output = NULL) {
-    $request = new Request(array(), array(), $attributes);
+    $request = new Request([], [], $attributes);
     $result = $this->controllerResolver->getController($request);
     if ($class) {
       $this->assertCallableController($result, $class, $output);
@@ -144,12 +167,12 @@ public function testGetController($attributes, $class, $output = NULL) {
    * Provides test data for testGetController().
    */
   public function providerTestGetController() {
-    return array(
+    return [
       // Tests passing a controller via the request.
-      array(array('_controller' => 'Drupal\Tests\Core\Controller\MockContainerAware::getResult'), 'Drupal\Tests\Core\Controller\MockContainerAware', 'This is container aware.'),
+      [['_controller' => 'Drupal\Tests\Core\Controller\MockContainerAware::getResult'], 'Drupal\Tests\Core\Controller\MockContainerAware', 'This is container aware.'],
       // Tests a request with no controller specified.
-      array(array(), FALSE)
-    );
+      [[], FALSE]
+    ];
   }
 
   /**
@@ -166,16 +189,18 @@ public function testGetControllerFromDefinition($definition, $output) {
    * Provides test data for testGetControllerFromDefinition().
    */
   public function providerTestGetControllerFromDefinition() {
-    return array(
+    return [
       // Tests a method on an object.
-      array(array(new MockController(), 'getResult'), 'This is a regular controller.'),
+      [[new MockController(), 'getResult'], 'This is a regular controller.'],
+      // Tests a method on an object.
+      [[new MockControllerPsr7(), 'getResult'], 'This is a regular controller.'],
       // Tests a function.
-      array('phpversion', phpversion()),
+      ['phpversion', phpversion()],
       // Tests an object using __invoke().
-      array(new MockInvokeController(), 'This used __invoke().'),
+      [new MockInvokeController(), 'This used __invoke().'],
       // Tests a class using __invoke().
-      array('Drupal\Tests\Core\Controller\MockInvokeController', 'This used __invoke().'),
-    );
+      ['Drupal\Tests\Core\Controller\MockInvokeController', 'This used __invoke().'],
+    ];
   }
   /**
    * Tests getControllerFromDefinition() without a callable.
@@ -219,8 +244,23 @@ public function testGetArgumentsWithRouteMatchAndRequest() {
     $this->assertEquals([RouteMatch::createFromRequest($request), $request], $arguments);
   }
 
+  /**
+   * Tests getArguments with a route match and a psr7 request.
+   *
+   * @covers ::getArguments
+   * @covers ::doGetArguments
+   */
+  public function testGetArgumentsWithRouteMatchAndPsr7Request() {
+    $request = Request::create('/test');
+    $mock_controller = new MockControllerPsr7();
+    $arguments = $this->controllerResolver->getArguments($request, [$mock_controller, 'getControllerWithRequestAndRouteMatch']);
+    $this->assertEquals(RouteMatch::createFromRequest($request), $arguments[0], 'Ensure that the route match object is passed along as well');
+    $this->assertInstanceOf('Psr\Http\Message\ServerRequestInterface', $arguments[1], 'Ensure that the psr7 object is passed along as well');
+  }
+
 }
 
+
 class MockController {
   public function getResult() {
     return 'This is a regular controller.';
@@ -231,6 +271,16 @@ public function getControllerWithRequestAndRouteMatch(RouteMatchInterface $route
   }
 
 }
+class MockControllerPsr7 {
+  public function getResult() {
+    return 'This is a regular controller.';
+  }
+
+  public function getControllerWithRequestAndRouteMatch(RouteMatchInterface $route_match, ServerRequestInterface $request) {
+    return 'this is another example controller';
+  }
+
+}
 class MockContainerInjection implements ContainerInjectionInterface {
   protected $result;
   public function __construct($result) {
@@ -242,14 +292,17 @@ public static function create(ContainerInterface $container) {
   public function getResult() {
     return $this->result;
   }
+
 }
 class MockContainerAware extends ContainerAware {
   public function getResult() {
     return 'This is container aware.';
   }
+
 }
 class MockInvokeController {
   public function __invoke() {
     return 'This used __invoke().';
   }
+
 }
