diff --git twitter_pull.field.inc twitter_pull.field.inc
new file mode 100644
index 0000000000000000000000000000000000000000..1d6c65a16328e76ba5c4ef9dff1a82aa91c876ad
--- /dev/null
+++ twitter_pull.field.inc
@@ -0,0 +1,185 @@
+<?php
+
+/**
+ * @file
+ * Implements a twitter pull field.
+ */
+
+/**
+ * Implements of hook_field_info().
+ */
+function twitter_pull_field_info() {
+  return array(
+    'twitter_pull_field' => array(
+      'label' => 'Twitter Feed',
+      'description' => 'Embed a twitter feed',
+      'settings' => array(),
+      'instance_settings' => array(),
+      'default_widget' => 'twitter_pull_field_feed',
+      'default_formatter' => 'twitter_pull_field',
+    )
+  );
+}
+
+/**
+ * Implements hook_field_widget_info().
+ */
+function twitter_pull_field_widget_info() {
+  return array(
+    'twitter_pull_field_feed' => array(
+      'label' => 'Feed',
+      'description' => 'Provides a twitter feed field',
+      'field types' => array('twitter_pull_field'),
+      'settings' => array(),
+      'behaviors' => array(
+        'multiple values' => FIELD_BEHAVIOR_DEFAULT,
+        'default value' => FIELD_BEHAVIOR_DEFAULT
+      ),
+    ),
+  );
+}
+
+/**
+ * Implements hook_field_widget_form().
+ */
+function twitter_pull_field_widget_form(&$form, &$form_state, $field, $instance, $langcode, $items, $delta, $element) {
+  // Don't need to check the type right now because we're only defining one
+  $element += array(
+    '#type' => 'fieldset',
+    '#tree' => TRUE,
+    '#required' => $element['#required'],
+    '#description' => $element['#description'],
+  );
+  
+  $element['key'] = array(
+    '#type' => 'textfield',
+    '#title' => t('Twitter key'),
+    '#default_value' => isset($items[$delta]['key']) ? $items[$delta]['key'] : '',
+    '#description' => t('Twitter key, which can be a username (prepended with @), hashtag (prepended with #), or a search term.'),
+    '#tree' => TRUE,
+  );
+  
+  $element['title'] = array(
+    '#type' => 'textfield',
+    '#title' => t('Title'),
+    '#default_value' => isset($items[$delta]['title']) ? $items[$delta]['title'] : 'Tweets',
+    '#description' => t('Title of the feed.'),
+    '#tree' => TRUE,
+  );
+  
+  $element['num'] = array(
+    '#type' => 'textfield',
+    '#title' => t('Number of tweets'),
+    '#default_value' => isset($items[$delta]['num']) ? $items[$delta]['num'] : '10',
+    '#description' => t('Number of tweets to retrieve from Twitter. Can\'t be more than 200.'),
+    '#tree' => TRUE,
+  );
+  
+  return $element;
+}
+
+/**
+ * Validates twitter feed.
+ */
+function twitter_pull_field_validate($entity_type, $entity, $field, $instance, $langcode, $items, &$errors) {
+  foreach ($items as $delta => $item) {
+    if (!is_numeric($item['num'])) {
+      $errors[$field['field_name']][$langcode][$delta][] = array(
+        'error' => 'integer_check', 
+        'message' => t('%name: Number of tweets must be an integer.', array('%name' => $instance['label'])),
+      );
+    }
+    
+    if ($item['num'] > 200) {
+      $errors[$field['field_name']][$langcode][$delta][] = array(
+        'error' => 'num_limit', 
+        'message' => t('%name: Number of tweets cannot be larger than 200.', array('%name' => $instance['label'])),
+      );
+    }
+  }
+}
+
+/**
+ * Implements of hook_field_widget_error().
+ */
+function twitter_pull_field_widget_error($element, $error, $form, &$form_state) {
+  switch ($error['error']) {
+    case 'integer_check':
+    case 'num_limit':
+      form_error($element['num'], $error['message']);
+      break;
+  }
+}
+
+/**
+ * Implements of hook_field_is_empty().
+ */
+function twitter_pull_field_is_empty($item, $field){
+  return empty($item) || empty($item['key']) || $item['key'] === '';
+}
+
+/**
+ * Implements hook_field_formatter_info().
+ */
+function twitter_pull_field_formatter_info() {
+  return array(
+    'twitter_pull_field' => array(
+      'label' => t('Twitter Feed'),
+      'field types' => array('twitter_pull_field'),
+      'settings' => array('key' => NULL, 'title' => 'Tweets', 'num' => 10, 'theme' => 'twitter_pull_listing'),
+    ),
+  );
+}
+
+/**
+ * Implements hook_field_formatter_settings_form().
+ */
+function twitter_pull_field_formatter_settings_form($field, $instance, $view_mode, $form, &$form_state) {
+  $display = $instance['display'][$view_mode];
+  $settings = $display['settings'];
+  $element = array();
+  
+  if ($display['type'] == 'twitter_pull_field') {
+    $element['theme'] = array(
+      '#title' => t('Theme'),
+      '#type' => 'textfield',
+      '#default_value' => 'twitter_pull_listing',
+    );
+  }
+  
+  return $element;
+}
+
+/**
+ * Implements hook_field_formatter_settings_summary().
+ */
+function twitter_pull_field_formatter_settings_summary($field, $instance, $view_mode) {
+  $display = $instance['display'][$view_mode];
+  $settings = $display['settings'];
+  
+  if ($display['type'] == 'twitter_pull_field'){
+    if (isset($settings['theme'])) {
+      $summary[] = t('Theme: @theme', array('@theme' => $settings['theme']));
+    }
+  }
+  
+  return implode('<br />', $summary);
+}
+
+/**
+ * Implements hook_field_formatter_view().
+ */
+function twitter_pull_field_formatter_view($entity_type, $entity, $field, $instance, $langcode, $items, $display){
+  $element = array();
+  
+  foreach ($items as $delta => $item) {
+    //Render the field
+    if ($display['type'] == 'twitter_pull_field') {
+      $element[$delta] = array(
+        '#markup' => twitter_pull_render($item['key'], $item['title'], $item['num'], $display['settings']['theme'])
+      );
+    }
+  }
+  
+  return $element;
+}
\ No newline at end of file
diff --git twitter_pull.install twitter_pull.install
index 9f3bf7cbe9ce01eee26a03e4665bfe8775bea357..3e1eb6bd839f8a1a370d2f68992d527a736392ba 100644
--- twitter_pull.install
+++ twitter_pull.install
@@ -14,6 +14,37 @@ function twitter_pull_schema() {
   return $schema;
 }
 
+/**
+ * Implements hook_field_schema().
+ */
+function twitter_pull_field_schema($field){
+  switch($field['type']){
+    case 'twitter_pull_field' :
+      $columns = array(
+        'key' => array(
+          'type' => 'varchar',
+          'length' => 512,
+          'default' => ''
+        ),
+        'title' => array(
+          'type' => 'varchar',
+          'length' => 512,
+          'default' => ''
+        ),
+        'num' => array(
+          'type' => 'int',
+          'default' => 10,
+        ),
+      );
+      $indexes = array();
+    break;
+  }
+  
+  return array(
+    'columns' => $columns,
+    'indexes' => $indexes
+  );
+}
 
 function twitter_pull__update_7101() {
   cache_clear_all('cache_pulled_tweets');
diff --git twitter_pull.module twitter_pull.module
index 892509e6c2339c6b7a6a55e864f1a09af0b367ca..229f77de326e930169ba69638ee9c317aeae87fd 100644
--- twitter_pull.module
+++ twitter_pull.module
@@ -10,6 +10,9 @@ define ('TWITTER_PULL_CACHE_LENGTH', 20); //-- cache for 20 minutes
 define ('TWITTER_PULL_EMPTY_MESSAGE', 'No Tweets');
 define ('TWITTER_PULL_CACHE_TABLE', 'cache_pulled_tweets');
 
+// Load all Field module hooks.
+module_load_include('inc', 'twitter_pull', 'twitter_pull.field');
+
 function twitter_pull_num_items() {
   return variable_get('twitter_pull_num_items', TWITTER_PULL_NUM_ITEMS);
 }
