diff --git a/userpoints.field.inc b/userpoints.field.inc
new file mode 100644
index 0000000..42b58d5
--- /dev/null
+++ b/userpoints.field.inc
@@ -0,0 +1,77 @@
+<?php
+/**
+ * @file
+ *   Denormalized/aggregated points field implementation.
+ */
+
+
+/**
+ * Implements hook_field_info().
+ *
+ * @todo Remove no_ui flag when this becomes feasible for all entities.
+ */
+function userpoints_field_info() {
+  return array(
+    'userpoints' => array(
+      'label' => t('Points'),
+      'description' => t('The total number of points associated with an entity (User).'),
+      'default_widget' => 'userpoints_hidden',
+      'default_formatter' => 'userpoints_default',
+      'no_ui' => TRUE,
+    ),
+  );
+}
+
+/**
+ * Implements hook_field_widget_info().
+ */
+function userpoints_field_widget_info() {
+  return array(
+    'userpoints_hidden' => array(
+      'label' => t('Points (hidden)'),
+      'description' => t('A dummy widget that displays the current point value associated with the entity.'),
+      'field types' => array('userpoints'),
+      'behaviors' => array(
+        'multiple values' => FIELD_BEHAVIOR_DEFAULT,
+        'default value' => FIELD_BEHAVIOR_DEFAULT,
+      ),
+    ),
+  );
+}
+
+/**
+ * Implements hook_field_formatter_info().
+ */
+function userpoints_field_formatter_info() {
+  return array(
+    'userpoints_default' => array(
+      'label' => t('Default'),
+      'field types' => array('userpoints'),
+    ),
+  );
+}
+
+/**
+ * Implements hook_field_widget_form().
+ *
+ * Do not display any widget. All points will be saved via the userpoints transaction system.
+ */
+function userpoints_field_widget_form(&$form, &$form_state, $field, $instance, $langcode, &$items, $delta, $element) {
+  return $element;
+}
+
+/**
+ * Implements hook_field_formatter_view().
+ */
+function userpoints_field_formatter_view($entity_type, $entity, $field, $instance, $langcode, $items, $display) {
+  $element = array();
+
+  foreach ($items as $delta => $item) {
+    $element[$delta] = array(
+      '#theme' => 'userpoints_points',
+      '#points' => $item['points'],
+    );
+  }
+
+  return $element;
+}
diff --git a/userpoints.install b/userpoints.install
index 990c381..8d19a50 100644
--- a/userpoints.install
+++ b/userpoints.install
@@ -206,6 +206,26 @@ function userpoints_schema() {
 }
 
 /**
+ * Implements hook_field_schema().
+ */
+function userpoints_field_schema($field) {
+  if ($field['type'] == 'userpoints') {
+    return array(
+      'columns' => array(
+        'points' => array(
+          'type' => 'numeric',
+          'not null' => TRUE,
+        ),
+        'max_points' => array(
+          'type' => 'numeric',
+          'not null' => TRUE,
+        ),
+      ),
+    );
+  }
+}
+
+/**
  * Implements hook_uninstall().
  */
 function userpoints_uninstall() {
@@ -331,4 +351,4 @@ function userpoints_update_7004(&$sandbox) {
   $sandbox['current_uid'] = $last_uid;
   // Set #finished based on sandbox.
   $sandbox['#finished'] = (empty($sandbox['max']) || $last_uid == 0) ? 1 : ($sandbox['current_uid'] / $sandbox['max']);
-}
\ No newline at end of file
+}
diff --git a/userpoints.module b/userpoints.module
index b37072c..5b69e08 100644
--- a/userpoints.module
+++ b/userpoints.module
@@ -26,6 +26,8 @@ define('USERPOINTS_CATEGORY_DEFAULT_TID', 'userpoints_category_default_tid');
 define('USERPOINTS_CATEGORY_PROFILE_DISPLAY_TID', 'userpoints_category_profile_display_tid');
 define('USERPOINTS_TRANSACTION_TIMESTAMP', 'userpoints_transaction_timestamp');
 
+module_load_include('inc', 'userpoints', 'userpoints.field');
+
 /**
  * Returns an array of common translation placeholders.
  */
@@ -1435,7 +1396,7 @@ function userpoints_entity_info() {
       'entity class' => 'UserpointsTransaction',
       'controller class' => 'UserpointsTransactionController',
       'metadata controller class' => 'UserpointsTransactionMetadataController',
-      'views controller class' => 'EntityDefaultViewsController',
+      'views controller class' => 'UserpointsTransactionViewsController',
       'base table' => 'userpoints_txn',
       'uri callback' => 'entity_class_uri',
       'fieldable' => TRUE,
diff --git a/userpoints.transaction.inc b/userpoints.transaction.inc
index 6535d89..c64c378 100644
--- a/userpoints.transaction.inc
+++ b/userpoints.transaction.inc
@@ -1430,3 +1431,22 @@ class UserpointsTransactionMetadataController extends EntityDefaultMetadataContr
     return $info;
   }
 }
+
+class UserpointsTransactionViewsController extends EntityDefaultViewsController {
+
+  public function views_data() {
+    $data = parent::views_data();
+
+    $data['userpoints_txn']['uid']['relationship'] = array(
+      'title' => t('User'),
+      'help' => t('Relate the userpoints transaction to the user.'),
+      'handler' => 'views_handler_relationship',
+      'base' => 'users',
+      'field' => 'uid',
+      'label' => t('User'),
+    );
+
+    return $data;
+  }
+
+}
diff --git a/userpoints_user/userpoints_user.info b/userpoints_user/userpoints_user.info
new file mode 100644
index 0000000..052945c
--- /dev/null
+++ b/userpoints_user/userpoints_user.info
@@ -0,0 +1,5 @@
+name = Userpoints User
+description = Attach user points to the user entity. It is recommended to enable this module.
+core = 7.x
+
+dependencies[] = userpoints
diff --git a/userpoints_user/userpoints_user.install b/userpoints_user/userpoints_user.install
new file mode 100644
index 0000000..4334516
--- /dev/null
+++ b/userpoints_user/userpoints_user.install
@@ -0,0 +1,61 @@
+<?php
+/**
+ * @file
+ *   Installation of userpoints field on the user entity.
+ */
+
+
+/**
+ * Implements hook_requirements().
+ */
+function userpoints_user_requirements($phase) {
+  $requirements = array();
+  $t = get_t();
+
+  if ($phase == 'install') {
+
+    if (field_info_field('field_userpoints')) {
+      $requirements['field_userpoints'] = array(
+        'title' => $t('Field userpoints exists'),
+        'description' => $t('The field %name already exists. Userpoints user must install this field itself. Please remove all instances of field_userpoints, refresh cache, and try again.', array('%name' => 'field_userpoints')),
+        'severity' => REQUIREMENT_ERROR,
+      );
+    }
+  }
+
+  return $requirements;
+}
+
+/**
+ * Implements hook_install().
+ */
+function userpoints_user_install() {
+  // Clear cache for Drush users.
+  cache_clear_all('field_info_fields', 'cache_field');
+
+  $field_info = array(
+    'field_name' => 'field_userpoints',
+    'type' => 'userpoints',
+    'cardinality' => 1,
+  );  
+
+  $field = field_create_field($field_info);
+
+  $instance_info = array(
+    'field_name' => 'field_userpoints',
+    'entity_type' => 'user',
+    'bundle' => 'user',
+    'label' => t('User Points'),
+    'description' => t('User points associated with this user account.'),
+    'required' => FALSE,
+  );  
+
+  $instance = field_create_instance($instance_info);
+}
+
+/**
+ * Implements hook_uninstall().
+ */
+function userpoints_user_uninstall() {
+  field_delete_instance('field_userpoints', TRUE);
+}
diff --git a/userpoints_user/userpoints_user.module b/userpoints_user/userpoints_user.module
new file mode 100644
index 0000000..9e74998
--- /dev/null
+++ b/userpoints_user/userpoints_user.module
@@ -0,0 +1,63 @@
+<?php
+/**
+ * @file
+ *   Userpoints user module.
+ */
+
+
+/**
+ * Implements hook_userpoints_transaction_update().
+ *
+ * Aggregate and save user points to field_userpoints.
+ */
+function userpoints_user_userpoints_transaction_update($entity) {
+  $wrapper = entity_metadata_wrapper('userpoints_transaction', $entity);
+  $account = $wrapper->user->value();
+
+  $account->field_userpoints['und'][0] = userpoints_user_get_points_from_transactions($account); 
+  user_save($account);
+}
+
+/**
+ * Implements hook_userpoints_transaction_insert().
+ *
+ * Aggregate and save user points to field_userpoints.
+ */
+function userpoints_user_userpoints_transaction_insert($entity) {
+  $wrapper = entity_metadata_wrapper('userpoints_transaction', $entity);
+  $account = $wrapper->user->value();
+
+  $account->field_userpoints['und'][0] = userpoints_user_get_points_from_transactions($account); 
+  user_save($account);
+}
+
+/**
+ * Retrieve points and max points for a user account based on userpoint 
+ * transactions.
+ *
+ * @param $account
+ *   The user account
+ * @return array
+ *   An associative array containing the number of points and max points for
+ *   the account.
+ */
+function userpoints_user_get_points_from_transactions($account) {
+  $item = array(
+    'points' => 0,
+    'max_points' => 0,
+  );
+
+  $query = db_select('userpoints_txn');
+  $query
+    ->condition('uid', $account->uid)
+    ->condition('status', 0)
+    ->fields('userpoints_txn', array('points'));
+  $result = $query->execute();
+
+  foreach ($result as $record) {
+    $item['points'] += $record->points;
+    $item['max_points'] += ($record->points > 0) ? $record->points : 0;
+  }
+
+  return $item;
+}
