diff --git a/javascript_libraries.admin.inc b/javascript_libraries.admin.inc
index ae9359f..a70119d 100644
--- a/javascript_libraries.admin.inc
+++ b/javascript_libraries.admin.inc
@@ -415,6 +415,14 @@ function javascript_libraries_edit_form($form, &$form_state, $library = array())
     '#access' => empty($library['type']) || $library['type'] == 'external',
   );
 
+  $cache_external_access = empty($library['type']) || $library['type'] == 'external';
+  $form['cache_external'] = array(
+    '#type' => 'checkbox',
+    '#title' => t('Cache script locally'),
+    '#default_value' => isset($library['cache']) ? $library['cache'] : FALSE,
+    '#access' => $cache_external_access,
+  );
+
   $file_access = empty($library['type']) || $library['type'] == 'file';
   $form['js_file_upload'] = array(
     '#type' => 'managed_file',
@@ -513,6 +521,7 @@ function javascript_libraries_edit_form_submit($form, &$form_state) {
         'name' => $form_state['values']['name'],
         'weight' => $form['#library']['weight'],
         'uri' => $form_state['values']['external_url'],
+        'cache' => $form_state['values']['cache_external'],
       );
       variable_set('javascript_libraries_custom_libraries', $custom);
       break;
diff --git a/javascript_libraries.module b/javascript_libraries.module
index 6857204..b62eabf 100644
--- a/javascript_libraries.module
+++ b/javascript_libraries.module
@@ -148,6 +148,25 @@ function javascript_libraries_valid_external_url($url) {
 }
 
 /**
+ * Implements hook_cron().
+ */
+function javascript_libraries_cron() {
+  $custom = variable_get('javascript_libraries_custom_libraries', array());
+  // Force an update once per day.
+  $last = variable_get('javascript_libraries_last_sync', 0);
+  $sync = REQUEST_TIME > $last + 86400;
+  foreach ($custom as $library) {
+    // Get/build local cached versions of external scripts.
+    if ($library['type'] == 'external' && $library['cache'] == 1) {
+      javascript_libraries_cache($library['uri'], $sync);
+    }
+  }
+  if ($sync) {
+    variable_set('javascript_libraries_last_sync', REQUEST_TIME);
+  }
+}
+
+/**
  * Implements hook_theme().
  */
 function javascript_libraries_theme() {
@@ -187,8 +206,21 @@ function javascript_libraries_init() {
     if ($library['scope'] == 'disabled') {
       continue;
     }
+
     $options = array();
-    $options['type'] = $library['type'];
+    // Test taken from drupal_get_js() for whether we are preprocessing.
+    $preprocess_js = (variable_get('preprocess_js', FALSE) && (!defined('MAINTENANCE_MODE') || MAINTENANCE_MODE != 'update'));
+    // Get/build local cached versions of external scripts.
+    if ($preprocess_js && $library['type'] == 'external' && $library['cache'] == 1) {
+      $local_path = javascript_libraries_cache($library['uri']);
+      if ($local_path) {
+        $options['type'] = 'file';
+        $library['uri'] = $local_path;
+      }
+    }
+    else {
+      $options['type'] = $library['type'];
+    }
     $options['scope'] = $library['scope'];
     $options['weight'] = $library['weight'] + $offset;
     $options['group'] = JS_THEME;
@@ -232,6 +264,60 @@ function javascript_libraries_library() {
 }
 
 /**
+ * Implements hook_flush_caches().
+ */
+function javascript_libraries_flush_caches() {
+  variable_del('javascript_libraries_last_sync');
+  javascript_libraries_cron();
+}
+
+/**
+ * Download/Synchronize/Cache tracking code file locally.
+ *
+ * Stolen from google analytics module.
+ *
+ * @param $uri
+ *   The full URL to the external javascript file.
+ * @param $sync_cached_file
+ *   Synchronize tracking code and update if remote file have changed.
+ * @return mixed
+ *   The path to the local javascript file on success, boolean FALSE on failure.
+ */
+function javascript_libraries_cache($uri, $sync_cached_file = FALSE) {
+  $path = 'public://javascript_libraries';
+
+  $file_destination = $path . '/' . basename(parse_url($uri, PHP_URL_PATH));
+  $file_exists = file_exists($file_destination);
+
+  if (!$file_exists || $sync_cached_file) {
+    // Download the library.
+    $result = drupal_http_request($uri);
+
+    if ($result->code != 200) {
+      watchdog('javascript_libraries', t('Error fetching remote file @uri.  http code: @code.'), array('@uri' => $uri, '@code' => $result->code), WATCHDOG_ERROR);
+      return FALSE;
+    }
+    if ($file_exists) {
+      // Save updated tracking code file to disk.
+      file_unmanaged_save_data($result->data, $file_destination, FILE_EXISTS_REPLACE);
+      watchdog('javascript_libraries', t('Locally cached javascript library has been updated.'), array(), WATCHDOG_INFO);
+      drupal_clear_js_cache();
+    }
+    else if (file_prepare_directory($path, FILE_CREATE_DIRECTORY)) {
+        // There is no need to flush JS here as core refreshes JS caches
+        // automatically if new files are added.
+        file_unmanaged_save_data($result->data, $file_destination, FILE_EXISTS_REPLACE);
+        watchdog('javascript_libraries', 'Locally cached javascript library has been saved.', array(), WATCHDOG_INFO);
+    }
+    else {
+      return FALSE;
+    }
+  }
+  // Return the local JS file path.
+  return file_create_url($file_destination);
+}
+
+/**
  * Implements hook_block_view_alter().
  */
 function javascript_libraries_block_view_alter(&$data, $block) {
