diff --git a/modules/render_cache_views/render_cache_views.info b/modules/render_cache_views/render_cache_views.info
index d9932fa..02a0a72 100644
--- a/modules/render_cache_views/render_cache_views.info
+++ b/modules/render_cache_views/render_cache_views.info
@@ -7,4 +7,5 @@ dependencies[] = render_cache
 dependencies[] = views
 dependencies[] = entity
 
+files[] = views/plugins/render_cache_hijack_views_handler_field_field.inc
 files[] = views/plugins/render_cache_hijack_views_plugin_row_node_view.inc
diff --git a/modules/render_cache_views/views/plugins/render_cache_hijack_views_handler_field_field.inc b/modules/render_cache_views/views/plugins/render_cache_hijack_views_handler_field_field.inc
new file mode 100644
index 0000000..3e3ebcf
--- /dev/null
+++ b/modules/render_cache_views/views/plugins/render_cache_hijack_views_handler_field_field.inc
@@ -0,0 +1,61 @@
+<?php
+
+class render_cache_hijack_views_handler_field_field extends views_handler_field_field {
+
+  /**
+   * Override views_handler_field_field::render() to add caching.
+   */
+  function set_items($values, $row_id) {
+    // In some cases the instance on the entity might be easy, see
+    // https://drupal.org/node/1161708 and https://drupal.org/node/1461536 for
+    // more information.
+    if (empty($values->_field_data[$this->field_alias]) || empty($values->_field_data[$this->field_alias]['entity']) || !isset($values->_field_data[$this->field_alias]['entity']->{$this->definition['field_name']})) {
+      return array();
+    }
+
+    $display = array(
+      'type' => $this->options['type'],
+      'settings' => $this->options['settings'],
+      'label' => 'hidden',
+      // Pass the View object in the display so that fields can act on it.
+      'views_view' => $this->view,
+      'views_field' => $this,
+      'views_row_id' => $row_id,
+    );
+
+
+    $entity_type = $values->_field_data[$this->field_alias]['entity_type'];
+    $entity = $this->get_value($values, 'entity');
+    if (!$entity) {
+      return array();
+    }
+
+    $langcode = $this->field_language($entity_type, $entity);
+    $render_array = render_cache_view_field($entity_type, $entity, $this->definition['field_name'], $display, $langcode);
+
+    $items = array();
+    if ($this->options['field_api_classes']) {
+      // Make a copy.
+      $array = $render_array;
+      return array(array('rendered' => drupal_render($render_array)));
+    }
+
+    foreach (element_children($render_array) as $count) {
+      $items[$count]['rendered'] = $render_array[$count];
+      // field_view_field() adds an #access property to the render array that
+      // determines whether or not the current user is allowed to view the
+      // field in the context of the current entity. We need to respect this
+      // parameter when we pull out the children of the field array for
+      // rendering.
+      if (isset($render_array['#access'])) {
+        $items[$count]['rendered']['#access'] = $render_array['#access'];
+      }
+      // Only add the raw field items (for use in tokens) if the current user
+      // has access to view the field content.
+      if ((!isset($items[$count]['rendered']['#access']) || $items[$count]['rendered']['#access']) && !empty($render_array['#items'][$count])) {
+        $items[$count]['raw'] = $render_array['#items'][$count];
+      }
+    }
+    return $items;
+  }
+}
diff --git a/modules/render_cache_views/views/render_cache_views.views.inc b/modules/render_cache_views/views/render_cache_views.views.inc
index 9023b26..de9371b 100644
--- a/modules/render_cache_views/views/render_cache_views.views.inc
+++ b/modules/render_cache_views/views/render_cache_views.views.inc
@@ -6,3 +6,16 @@
 function render_cache_views_views_plugins_alter(&$plugins) {
   $plugins['row']['node']['handler'] = 'render_cache_hijack_views_plugin_row_node_view';
 }
+
+/**
+ * Implements hook_field_views_data_alter().
+ */
+function render_cache_field_views_data_alter(&$result, $field, $module) {
+  foreach ($result as $table => $columns) {
+    foreach ($columns as $key => $column) {
+      if (!empty($column['field']['handler']) && $column['field']['handler'] == 'views_handler_field_field') {
+        $result[$table][$key]['field']['handler'] = 'render_cache_hijack_views_handler_field_field';
+      }
+    }
+  }
+}
diff --git a/render_cache.module b/render_cache.module
index 6640c69..e1a8f06 100644
--- a/render_cache.module
+++ b/render_cache.module
@@ -31,7 +31,7 @@ function render_cache_entity_view_callback($entities, $view_mode, $langcode = NU
   // Setup drupal_render style cache array.
   $cache_info = render_cache_cache_info_defaults();
   $cache_info['keys'] = array(
-    'render_cache',
+    'entity',
     $entity_type,
     $view_mode,
   );
@@ -97,40 +97,7 @@ function render_cache_entity_view_callback($entities, $view_mode, $langcode = NU
       $cid = $cid_map[$id];
       $render = $rendered[$id];
 
-      if (isset($cache_info['granularity']) && $cache_info['granularity'] != DRUPAL_NO_CACHE) {
-        if (empty($cache_info['render_cache_render_to_markup'])) {
-          cache_set($cid, $render, 'cache_render');
-        }
-        else {
-          // Process markup with drupal_render() caching.
-          $render['#cache'] = $cache_info;
-
-          // Explicitly set cache id.
-          $render['#cache']['cid'] = $cid;
-
-          $render_cache_attached = array();
-          // Preserve some properties in #attached?
-          if (!empty($cache_info['render_cache_render_to_markup']['preserve properties']) &&
-              is_array($cache_info['render_cache_render_to_markup']['preserve properties'])) {
-            foreach ($cache_info['render_cache_render_to_markup']['preserve properties'] as $key) {
-              if (isset($render[$key])) {
-                $render_cache_attached[$key] = $render[$key];
-              }
-            }
-          }
-          if (!empty($render_cache_attached)) {
-            $render['#attached']['render_cache'] = $render_cache_attached;
-          }
-
-          // Do we want to render now?
-          if (empty($cache_info['render_cache_render_to_markup']['cache late'])) {
-            // And save things. Also add our preserved properties back.
-            $render = array(
-              '#markup' => drupal_render($render),
-            ) + $render_cache_attached;
-          }
-        }
-      }
+      _render_cache_pre_render($render, $cid, $cache_info);
 
       $cached_entities[$cid] = (object) array(
         'data' => $render,
@@ -154,16 +121,7 @@ function render_cache_entity_view_callback($entities, $view_mode, $langcode = NU
     $cid = $cid_map[$id];
     if (!empty($cached_entities[$cid]->data)) {
       $render = $cached_entities[$cid]->data;
-
-      // Potentially merge back previously saved properties.
-      if (!empty($render['#attached']['render_cache'])) {
-        $render += $render['#attached']['render_cache'];
-        unset($render['#attached']['render_cache']);
-      }
-
-      // Run any post-render callbacks.
-      render_cache_process_attached_callbacks($render, $id);
-
+      _render_cache_post_render($render, $id);
       $return[$id] = $render;
       $return[$id]['#weight'] = $weight;
     }
@@ -173,6 +131,56 @@ function render_cache_entity_view_callback($entities, $view_mode, $langcode = NU
   return array($entity_type => $return);
 }
 
+function _render_cache_pre_render(array &$render, $cid, $cache_info) {
+  if (isset($cache_info['granularity']) && $cache_info['granularity'] != DRUPAL_NO_CACHE) {
+    if (empty($cache_info['render_cache_render_to_markup'])) {
+      cache_set($cid, $render, 'cache_render');
+    }
+    else {
+      // Process markup with drupal_render() caching.
+      $render['#cache'] = $cache_info;
+
+      // Explicitly set cache id.
+      $render['#cache']['cid'] = $cid;
+
+      $render_cache_attached = array();
+      // Preserve some properties in #attached?
+      if (!empty($cache_info['render_cache_render_to_markup']['preserve properties']) &&
+        is_array($cache_info['render_cache_render_to_markup']['preserve properties'])) {
+        foreach ($cache_info['render_cache_render_to_markup']['preserve properties'] as $key) {
+          if (isset($render[$key])) {
+            $render_cache_attached[$key] = $render[$key];
+          }
+        }
+      }
+      if (!empty($render_cache_attached)) {
+        $render['#attached']['render_cache'] = $render_cache_attached;
+      }
+
+      // Do we want to render now?
+      if (empty($cache_info['render_cache_render_to_markup']['cache late'])) {
+        // And save things. Also add our preserved properties back.
+        $render = array(
+            '#markup' => drupal_render($render),
+          ) + $render_cache_attached;
+      }
+    }
+  }
+
+  return $render;
+}
+
+function _render_cache_post_render(array &$render, $id) {
+  // Potentially merge back previously saved properties.
+  if (!empty($render['#attached']['render_cache'])) {
+    $render += $render['#attached']['render_cache'];
+    unset($render['#attached']['render_cache']);
+  }
+
+  // Run any post-render callbacks.
+  render_cache_process_attached_callbacks($render, $id);
+}
+
 /**
  * Invokes attached post-render callbacks.
  *
@@ -235,7 +243,7 @@ function render_cache_cache_info_defaults() {
 }
 
 /**
- * Retrieve cache ID to use for render caching.
+ * Retrieve cache ID to use for entity render caching.
  *
  * @param object $entity
  *   The entity object being rendered.
@@ -243,13 +251,16 @@ function render_cache_cache_info_defaults() {
  *   A drupal_render style cache array().
  * @param array $context
  *   The context of the entity, with the following keys:
- *
  *   - entity_type
  *   - entity_id
  *   - entity_revision_id
  *   - bundle
  *   - langcode
  *   - view_mode
+ *   If a field is being rendered, the following additional keys are required:
+ *   - field_name
+ *   - deltas
+ *   - display
  *
  * @return string
  */
@@ -259,7 +270,7 @@ function render_cache_get_entity_cid($entity, &$cache_info, $context) {
   }
 
   $cache_info += render_cache_cache_info_defaults();
-  
+
   drupal_alter('render_cache_entity_cache_info', $cache_info, $entity, $context);
 
   $cid_parts = array();
@@ -276,14 +287,21 @@ function render_cache_get_entity_cid($entity, &$cache_info, $context) {
   // Calculate hash to expire cached items automatically.
   $hash['id'] = !empty($context['entity_revision_id']) ? $context['entity_revision_id'] : $context['entity_id'];
   $hash['bundle'] = !empty($context['bundle']) ? $context['bundle'] : $context['entity_type'];
+  $hash['langcode'] = !empty($context['langcode']) ? $context['langcode'] : $GLOBALS['language_content']->language;
   $hash['modified'] = entity_modified_last($context['entity_type'], $entity);
   $hash['render_method'] = !empty($cache_info['render_cache_render_to_markup']);
   if ($hash['render_method']) {
     $hash['render_options'] = serialize($cache_info['render_cache_render_to_markup']);
   }
 
-  // Generally hash per view_mode - its unlikely they are the same.
-  $hash['view_mode'] = !empty($context['view_mode']) ? $context['view_mode'] : 'default';
+  if (!empty($context['field_name'])) {
+    $hash['deltas'] = implode(',', $context['deltas']);
+    $hash['display'] = serialize(array_intersect_key($context['display'], array('type' => '', 'settings' => '')));
+  }
+  else {
+    // Generally hash per view_mode - its unlikely they are the same.
+    $hash['view_mode'] = !empty($context['view_mode']) ? $context['view_mode'] : 'default';
+  }
 
   // Allow modules to modify $hash for custom invalidating.
   drupal_alter('render_cache_entity_hash', $hash, $entity, $cache_info, $context);
@@ -323,7 +341,7 @@ function render_cache_flush_caches() {
  *
  * @param $entity_type
  *   The type of the entity.
- * $parem $entity
+ * $param $entity
  *   The entity to render.
  * $param $view_mode
  *   A view mode as used by this entity type, e.g. 'full', 'teaser'...
@@ -352,3 +370,98 @@ function node_render_cache_entity_hash_alter(&$hash, $entity, $cache_info, $cont
     $hash['node_comment_count'] = $entity->comment_count;
   }
 }
+
+/**
+ * Helper function to view a single entity field.
+ *
+ * This can be used to replace field_view_field().
+ *
+ * @param string $entity_type
+ *   The type of $entity; e.g., 'node' or 'user'.
+ * @param object $entity
+ *   The entity containing the field to display. Must at least contain the id
+ *   key and the field data to display.
+ * @param string $field_name
+ *   The name of the field to display.
+ * @param string|array $display
+ *   Can be either:
+ *   - The name of a view mode. The field will be displayed according to the
+ *     display settings specified for this view mode in the $instance
+ *     definition for the field in the entity's bundle.
+ *     If no display settings are found for the view mode, the settings for
+ *     the 'default' view mode will be used.
+ *   - An array of display settings, as found in the 'display' entry of
+ *     $instance definitions. The following key/value pairs are allowed:
+ *     - label: (string) Position of the label. The default 'field' theme
+ *       implementation supports the values 'inline', 'above' and 'hidden'.
+ *       Defaults to 'above'.
+ *     - type: (string) The formatter to use. Defaults to the
+ *       'default_formatter' for the field type, specified in
+ *       hook_field_info(). The default formatter will also be used if the
+ *       requested formatter is not available.
+ *     - settings: (array) Settings specific to the formatter. Defaults to the
+ *       formatter's default settings, specified in
+ *       hook_field_formatter_info().
+ *     - weight: (float) The weight to assign to the renderable element.
+ *       Defaults to 0.
+ * @param string $langcode
+ *   (Optional) The language the field values are to be shown in. The site's
+ *   current language fallback logic will be applied no values are available
+ *   for the language. If no language is provided the current language will be
+ *   used.
+ *
+ * @return
+ *   A renderable array for the field value.
+ */
+function render_cache_view_field($entity_type, $entity, $field_name, $display = array(), $langcode = NULL) {
+  // If the entity has no field value, just return nothing.
+  $items = field_get_items($entity_type, $entity, $field_name);
+  if (empty($items)) {
+    return array();
+  }
+
+  // Prepare context
+  $context = array(
+    'entity_type' => $entity_type,
+    'field_name' => $field_name,
+    'display' => $display,
+    'langcode' => field_language($entity_type, $entity, $field_name, $langcode),
+    'deltas' => array_keys($items),
+  );
+
+  // Setup drupal_render style cache array.
+  $cache_info = render_cache_cache_info_defaults();
+  $cache_info['keys'] = array(
+    'field',
+    $entity_type,
+    $field_name,
+  );
+
+  drupal_alter('render_cache_field_default_cache_info', $cache_info, $context);
+
+  list($entity_id, $entity_revision_id, $bundle) = entity_extract_ids($entity_type, $entity);
+  $entity_context = $context + array(
+    'entity_id' => $entity_id,
+    'entity_revision_id' => $entity_revision_id,
+    'bundle' => $bundle,
+  );
+  $cid = render_cache_get_entity_cid($entity, $cache_info, $entity_context);
+  $cache = cache_get($cid, 'cache_render');
+
+  if (!$cache) {
+    $field_render = field_view_field($entity_type, $entity, $field_name, $display, $langcode);
+
+    _render_cache_pre_render($field_render, $cid, $cache_info);
+
+    $cache = (object) array(
+      'data' => $field_render,
+    );
+  }
+
+  $render = $cache->data;
+
+  // @todo Not sure what should be used for the second parameter here?
+  _render_cache_post_render($render, $cid);
+
+  return $render;
+}
