diff --git a/core/lib/Drupal/Core/CoreBundle.php b/core/lib/Drupal/Core/CoreBundle.php
index 48684e5..d8f6960 100644
--- a/core/lib/Drupal/Core/CoreBundle.php
+++ b/core/lib/Drupal/Core/CoreBundle.php
@@ -93,6 +93,8 @@ public function build(ContainerBuilder $container) {
       ->addTag('nested_matcher', array('method' => 'setInitialMatcher'));
     $container->register('http_method_matcher', 'Drupal\Core\Routing\HttpMethodMatcher')
       ->addTag('nested_matcher', array('method' => 'addPartialMatcher'));
+    $container->register('mime_type_matcher', 'Drupal\Core\Routing\MimeTypeMatcher')
+      ->addTag('nested_matcher', array('method' => 'addPartialMatcher'));
     $container->register('first_entry_final_matcher', 'Drupal\Core\Routing\FirstEntryFinalMatcher')
       ->addTag('nested_matcher', array('method' => 'setFinalMatcher'));
 
diff --git a/core/lib/Drupal/Core/Routing/MimeTypeMatcher.php b/core/lib/Drupal/Core/Routing/MimeTypeMatcher.php
new file mode 100644
index 0000000..c6ebb6f
--- /dev/null
+++ b/core/lib/Drupal/Core/Routing/MimeTypeMatcher.php
@@ -0,0 +1,57 @@
+<?php
+
+/**
+ * @file
+ * Definition of Drupal\Core\Routing\MimeTypeMatcher.
+ */
+
+namespace Drupal\Core\Routing;
+
+use Symfony\Component\HttpFoundation\Request;
+use Symfony\Component\Routing\RouteCollection;
+use Symfony\Component\Routing\Exception\RouteNotFoundException;
+
+/**
+ * This class filters routes based on their HTTP Method.
+ */
+class MimeTypeMatcher extends PartialMatcher {
+
+  /**
+   * Matches a request against multiple routes.
+   *
+   * @param \Symfony\Component\HttpFoundation\Request $request
+   *   A Request object against which to match.
+   *
+   * @return \Symfony\Component\Routing\RouteCollection
+   *   A RouteCollection of matched routes.
+   */
+  public function matchRequestPartial(Request $request) {
+
+    // Generates a list of Symfony formats matching the acceptable MIME types.
+    // @todo replace by proper content negotiation library.
+    $acceptable_mime_types = $request->getAcceptableContentTypes();
+    $acceptable_formats = array_map(array($request, 'getFormat'), $acceptable_mime_types);
+
+    $collection = new RouteCollection();
+
+    foreach ($this->routes->all() as $name => $route) {
+      // _format could be a |-delimited list of supported formats.
+      $supported_formats = array_filter(explode('|', $route->getRequirement('_format')));
+      // The route partially matches if it doesn't care about format, if it
+      // explicitly allows any format, or if one of its allowed formats is
+      // in the request's list of acceptable formats.
+      if (empty($supported_formats) || in_array('*/*', $acceptable_mime_types) || array_intersect($acceptable_formats, $supported_formats)) {
+        $collection->add($name, $route);
+      }
+    }
+
+    if (!count($collection)) {
+      // @todo update with UnsupportedMediaTypeException when available
+      // @see http://drupal.org/node/1831074
+      throw new RouteNotFoundException();
+    }
+
+    return $collection;
+  }
+
+}
diff --git a/core/modules/system/lib/Drupal/system/Tests/Routing/MimeTypeMatcherTest.php b/core/modules/system/lib/Drupal/system/Tests/Routing/MimeTypeMatcherTest.php
new file mode 100644
index 0000000..cbd1b89
--- /dev/null
+++ b/core/modules/system/lib/Drupal/system/Tests/Routing/MimeTypeMatcherTest.php
@@ -0,0 +1,81 @@
+<?php
+
+/**
+ * @file
+ * Definition of Drupal\system\Tests\Routing\MimeTypeMatcherTest.
+ */
+
+namespace Drupal\system\Tests\Routing;
+
+use Symfony\Component\HttpFoundation\Request;
+use Symfony\Component\Routing\Route;
+use Symfony\Component\Routing\RouteCollection;
+use Symfony\Component\Routing\Exception\MethodNotAllowedException;
+
+use Drupal\simpletest\UnitTestBase;
+use Drupal\Core\Routing\MimeTypeMatcher;
+use Drupal\Core\Routing\NestedMatcher;
+use Drupal\Core\Routing\FirstEntryFinalMatcher;
+
+use Exception;
+
+/**
+ * Basic tests for the MimeTypeMatcher class.
+ */
+class MimeTypeMatcherTest extends UnitTestBase {
+
+  /**
+   * A collection of shared fixture data for tests.
+   *
+   * @var RoutingFixtures
+   */
+  protected $fixtures;
+
+  public static function getInfo() {
+    return array(
+      'name' => 'Partial matcher MIME types tests',
+      'description' => 'Confirm that the mime types partial matcher is functioning properly.',
+      'group' => 'Routing',
+    );
+  }
+
+  function __construct($test_id = NULL) {
+    parent::__construct($test_id);
+
+    $this->fixtures = new RoutingFixtures();
+  }
+
+  /**
+   * Confirms that the MimeType matcher matches properly.
+   */
+  public function testFilterRoutes() {
+
+    $matcher = new MimeTypeMatcher();
+    $matcher->setCollection($this->fixtures->sampleRouteCollection());
+
+    // Tests basic JSON request.
+    $request = Request::create('path/two', 'GET');
+    $request->headers->set('Accept', 'application/json, text/xml;q=0.9');
+    $routes = $matcher->matchRequestPartial($request);
+    $this->assertEqual(count($routes->all()), 4, 'The correct number of routes was found.');
+    $this->assertNotNull($routes->get('route_c'), 'The json route was found.');
+    $this->assertNull($routes->get('route_e'), 'The html route was not found.');
+
+    // Tests JSON request with alternative JSON MIME type Accept header.
+    $request = Request::create('path/two', 'GET');
+    $request->headers->set('Accept', 'application/x-json, text/xml;q=0.9');
+    $routes = $matcher->matchRequestPartial($request);
+    $this->assertEqual(count($routes->all()), 4, 'The correct number of routes was found.');
+    $this->assertNotNull($routes->get('route_c'), 'The json route was found.');
+    $this->assertNull($routes->get('route_e'), 'The html route was not found.');
+
+    // Tests basic HTML request.
+    $request = Request::create('path/two', 'GET');
+    $request->headers->set('Accept', 'text/html, text/xml;q=0.9');
+    $routes = $matcher->matchRequestPartial($request);
+    $this->assertEqual(count($routes->all()), 4, 'The correct number of routes was found.');
+    $this->assertNull($routes->get('route_c'), 'The json route was not found.');
+    $this->assertNotNull($routes->get('route_e'), 'The html route was found.');
+  }
+
+}
diff --git a/core/modules/system/lib/Drupal/system/Tests/Routing/RoutingFixtures.php b/core/modules/system/lib/Drupal/system/Tests/Routing/RoutingFixtures.php
index f243ff1..db001c2 100644
--- a/core/modules/system/lib/Drupal/system/Tests/Routing/RoutingFixtures.php
+++ b/core/modules/system/lib/Drupal/system/Tests/Routing/RoutingFixtures.php
@@ -61,6 +61,7 @@ public function sampleRouteCollection() {
 
     $route = new Route('path/two');
     $route->setRequirement('_method', 'GET');
+    $route->setRequirement('_format', 'json');
     $collection->add('route_c', $route);
 
     $route = new Route('path/three');
@@ -68,6 +69,7 @@ public function sampleRouteCollection() {
 
     $route = new Route('path/two');
     $route->setRequirement('_method', 'GET|HEAD');
+    $route->setRequirement('_format', 'html');
     $collection->add('route_e', $route);
 
     return $collection;
