diff --git a/core/misc/matchMedia/matchMedia.js b/core/misc/matchMedia/matchMedia.js
new file mode 100644
index 0000000..c680c4b
--- /dev/null
+++ b/core/misc/matchMedia/matchMedia.js
@@ -0,0 +1,36 @@
+/*! matchMedia() polyfill - Test a CSS media type/query in JS. Authors & copyright (c) 2012: Scott Jehl, Paul Irish, Nicholas Zakas. Dual MIT/BSD license */
+
+window.matchMedia = window.matchMedia || (function( doc, undefined ) {
+
+  "use strict";
+
+  var bool,
+      docElem = doc.documentElement,
+      refNode = docElem.firstElementChild || docElem.firstChild,
+      // fakeBody required for <FF4 when executed in <head>
+      fakeBody = doc.createElement( "body" ),
+      div = doc.createElement( "div" );
+
+  div.id = "mq-test-1";
+  div.style.cssText = "position:absolute;top:-100em";
+  fakeBody.style.background = "none";
+  fakeBody.appendChild(div);
+
+  return function(q){
+
+    div.innerHTML = "&shy;<style media=\"" + q + "\"> #mq-test-1 { width: 42px; }</style>";
+
+    docElem.insertBefore( fakeBody, refNode );
+    bool = div.offsetWidth === 42;
+    docElem.removeChild( fakeBody );
+
+    return {
+      matches: bool,
+      media: q
+    };
+
+  };
+
+}( document ));
+
+
diff --git a/core/misc/matchmedia.js b/core/misc/matchmedia.js
new file mode 100644
index 0000000..3f52e50
--- /dev/null
+++ b/core/misc/matchmedia.js
@@ -0,0 +1,120 @@
+/**
+ * Wrap the behavior of window.matchMedia in window.DrupalMatchMedia.
+ *
+ * @see http://dev.w3.org/csswg/cssom-view/#widl-Window-matchMedia-MediaQueryList-DOMString-query
+ *
+ * Test whether a CSS media type or media query applies. Register listeners
+ * to MediaQueryList objects.
+ *
+ * DrupalMatchMedia wraps window.matchMedia to add the addEventListener and
+ * removeEventListener functions. If these functions exist on the native
+ * window.matchMedia object it uses them, if they don't exist (which means
+ * window.matchMedia was polyfilled) it uses our implementation of those
+ * functions which trigger on window resize and orientationchange.
+ */
+(function (window) {
+  "use strict";
+  // Allow users to alter the timespan in which eventlisteners for
+  // DrupalMatchmedia can only be called once.
+  window.drupalSettings.DrupalMatchMedia = window.drupalSettings.DrupalMatchMedia || {debounce: 250};
+
+  // Ensure addEventListener and removeEventListener are defined.
+  // @todo: Drop this when we stop support for IE8.
+  window.addEventListener = window.addEventListener || window.attachEvent || function () {};
+  window.removeEventListener = window.removeEventListener || window.detachEvent || function () {};
+
+  /**
+   * A wrapper around the native MediaQueryList object.
+   *
+   * @param {String} q
+   *   A media query e.g. "screen" or "screen and (min-width: 28em)".
+   */
+  window.DrupalMediaQueryList = function (q) {
+    this._matchMedia = window.matchMedia(q);
+    this.media = this._matchMedia.media;
+    this.matches = this._matchMedia.matches;
+  };
+
+  /**
+   * Implement the addListener and removeListener methods.
+   */
+  window.DrupalMediaQueryList.prototype = {
+    listeners: [],
+
+    /**
+     * Wrap the addListener method of the MediaQueryList object.
+     *
+     * @param {Function} callback
+     *   The callback to be invoked when the associated media query list changes
+     *   in evaluation.
+     */
+    addListener: function (callback) {
+      var handler = (function (mql, debounced) {
+        return function () {
+          var self = mql;
+          var cb = debounced;
+          cb.call(self, self);
+        };
+      })(this, debounce(callback, window.drupalSettings.DrupalMatchMedia.debounce));
+      this.listeners.push({
+        'callback': callback,
+        'handler': handler
+      });
+      window.addEventListener('resize', handler);
+      window.addEventListener('orientationchange', handler);
+    },
+
+    /**
+     * Polyfill the removeListener method of the MediaQueryList object.
+     *
+     * @param {Function} callback
+     *   The callback to be removed from the set of listeners.
+     */
+    removeListener: function (callback) {
+      for (var i = 0, listeners = this.listeners; i < listeners.length; i++) {
+        if (listeners[i].callback === callback) {
+          window.removeEventListener('resize', listeners[i].handler);
+          window.removeEventListener('orientationchange', listeners[i].handler);
+          listeners.splice(i, 1);
+        }
+      }
+    }
+  };
+
+  /**
+   * Limits the invocations of a function in a given time frame.
+   *
+   * @param {Function} callback
+   *   The function to be invoked.
+   *
+   * @param {Number} wait
+   *   The time period within which the callback function should only be
+   *   invoked once. For example if the wait period is 250ms, then the callback
+   *   will only be called at most 4 times per second.
+   */
+  function debounce (callback, wait) {
+    var timeout, result;
+    return function () {
+      var context = this;
+      var args = arguments;
+      var later = function () {
+        timeout = null;
+        result = callback.apply(context, args);
+      };
+      window.clearTimeout(timeout);
+      timeout = window.setTimeout(later, wait);
+      return result;
+    };
+  }
+
+  /**
+   * Return a DrupalMediaQueryList.
+   *
+   * @param {String} q
+   *   A media query e.g. "screen" or "screen and (min-width: 28em)". The media
+   *   query is checked for applicability before the object is returned.
+   */
+  window.DrupalMatchMedia = function(q) {
+    return new window.DrupalMediaQueryList(q);
+  };
+})(window);
diff --git a/core/modules/system/system.module b/core/modules/system/system.module
index ea3dadc..048ea7a 100644
--- a/core/modules/system/system.module
+++ b/core/modules/system/system.module
@@ -1380,6 +1380,30 @@ function system_library_info() {
     ),
   );
 
+  // DrupalMatchMedia.
+  $libraries['drupal.matchmedia'] = array(
+    'title' => 'window.matchMedia wrapper',
+    'website' => 'http://drupal.org/node/1815602',
+    'version' => VERSION,
+    'js' => array(
+      'core/misc/matchmedia.js' => array(),
+    ),
+    'dependencies' => array(
+      array('system', 'drupalSettings'),
+      array('system', 'matchMedia'),
+    )
+  );
+
+  // matchMedia.
+  $libraries['matchMedia'] = array(
+    'title' => 'window.matchMedia polyfill',
+    'website' => 'https://github.com/paulirish/matchMedia.js',
+    'version' => '1.0',
+    'js' => array(
+      'core/misc/matchMedia/matchMedia.js' => array(),
+    ),
+  );
+
   // Farbtastic.
   $libraries['jquery.farbtastic'] = array(
     'title' => 'Farbtastic',
