diff --git a/modules/salesforce_pull/salesforce_pull.module b/modules/salesforce_pull/salesforce_pull.module
index b5c684d..9ca32d1 100644
--- a/modules/salesforce_pull/salesforce_pull.module
+++ b/modules/salesforce_pull/salesforce_pull.module
@@ -202,6 +202,57 @@ function salesforce_pull_check_throttle() {
 }
 
 /**
+ * Determines whether record should be pulled from Salesforce.
+ *
+ * @param array $record
+ *   A single Salesforce record as returned by SOQL pull query.
+ *
+ * @return bool
+ *   FALSE if the record should not be pulled from Salesforce.
+ */
+function salesforce_pull_record_allowed($record) {
+  // Invoke a hook to allow other modules to prevent this record from being
+  // pulled.
+  foreach (module_implements('salesforce_pull_record_allowed') as $module) {
+    if (module_invoke($module, 'salesforce_pull_record_allowed', $record) === FALSE) {
+      return FALSE;
+    }
+  }
+
+  return TRUE;
+}
+
+/**
+ * Determines whether to allow processing of a mapped Drupal entity.
+ *
+ * Allows other modules to prevent processing and saving of a Drupal entity
+ * that is mapped to a Salesforce pull queue item.
+ *
+ * @param string $drupal_entity_type
+ *   The entity type of the mapped Drupal entity.
+ * @param EntityMetadataWrapper $entity_wrapper
+ *   Entity wrapper for the mapped Drupal entity.
+ * @param array $sf_object
+ *   The pulled Salesforce record, as claimed from the pull queue.
+ * @param SalesforceMapping $sf_mapping
+ *   Mapping object for this pull operation.
+ *
+ * @return bool
+ *   FALSE if the queue item should be skipped, and the pull ignored.
+ */
+function salesforce_pull_entity_allowed($drupal_entity_type, $entity_wrapper, $sf_object, $sf_mapping) {
+  // Invoke a hook to allow other modules to stop processing of Salesforce
+  // record and prevent this entity from being saved in Drupal.
+  foreach (module_implements('salesforce_pull_entity_allowed') as $module) {
+    if (module_invoke($module, 'salesforce_pull_entity_allowed', $drupal_entity_type, $entity_wrapper, $sf_object, $sf_mapping) === FALSE) {
+      return FALSE;
+    }
+  }
+
+  return TRUE;
+}
+
+/**
  * Pull updated records from Salesforce and place them in the queue.
  *
  * Executes a SOQL query based on defined mappings, loops through the results,
@@ -238,6 +289,10 @@ function salesforce_pull_get_updated_records() {
     if (!isset($results['errorCode'])) {
       // Write items to the queue.
       foreach ($results['records'] as $result) {
+        // Skip items that are not allowed to be pulled.
+        if (!salesforce_pull_record_allowed($result)) {
+          continue;
+        }
         $queue_item = array('update' => $result);
         $queue->createItem($queue_item);
       }
@@ -251,6 +306,10 @@ function salesforce_pull_get_updated_records() {
         if (!isset($new_result['errorCode'])) {
           // Write items to the queue.
           foreach ($new_result['records'] as $result) {
+            // Skip items that are not allowed to be pulled.
+            if (!salesforce_pull_record_allowed($result)) {
+              continue;
+            }
             $queue_item = array('update' => $result);
             $queue->createItem($queue_item);
           }
@@ -476,6 +535,11 @@ function salesforce_pull_process_updated_records($sf_object) {
 
           salesforce_pull_map_fields($sf_mapping->field_mappings, $wrapper, $sf_object);
 
+          // Allow other modules to prevent this entity from being saved.
+          if (!salesforce_pull_entity_allowed($sf_mapping->drupal_entity_type, $wrapper, $sf_object, $sf_mapping)) {
+            continue;
+          }
+
           // Allow modules to react just prior to entity save.
           module_invoke_all('salesforce_pull_entity_presave', $wrapper->value(), $sf_object, $sf_mapping);
 
@@ -512,6 +576,11 @@ function salesforce_pull_process_updated_records($sf_object) {
           }
         }
 
+        // Allow other modules to prevent this entity from being saved.
+        if (!salesforce_pull_entity_allowed($sf_mapping->drupal_entity_type, $wrapper, $sf_object, $sf_mapping)) {
+          continue;
+        }
+
         // If no id exists, the insert failed and we cannot create a mapping
         // object. We are left with no choice but to throw an exception.
         list($entity_id) = entity_extract_ids($sf_mapping->drupal_entity_type, $entity);
diff --git a/salesforce.api.php b/salesforce.api.php
index 6977d59..ec61b7d 100644
--- a/salesforce.api.php
+++ b/salesforce.api.php
@@ -178,6 +178,48 @@ function hook_salesforce_pull_entity_value_alter(&$value, $field_map, $sf_object
 }
 
 /**
+ * Prevent a Salesforce object from being added to the pull queue.
+ *
+ * For example, prevent pull of Contacts without email address.
+ *
+ * @param array $result
+ *   A single Salesforce record as returned by SOQL pull query.
+ *
+ * @return bool
+ *   FALSE if the object should not be pulled from Salesforce.
+ */
+function hook_salesforce_pull_record_allowed($result) {
+  // Don't pull any Contact records without email, or with example.com address.
+  if ($result['attributes']['type'] == 'Contact'
+  && (empty($result['Email']) || strpos($result['Email'], 'example.com'))) {
+    return FALSE;
+  }
+}
+
+/**
+ * Skip processing of a Salesforce pull queue item.
+ *
+ * For example, never pull to user 1.
+ *
+ * @param string $drupal_entity_type
+ *   The entity type of the existing or new mapped Drupal entity.
+ * @param EntityMetadataWrapper $entity_wrapper
+ *   Entity wrapper for the mapped Drupal entity.
+ * @param array $sf_object
+ *   The pulled Salesforce record, as claimed from the pull queue.
+ * @param SalesforceMapping $sf_mapping
+ *   Mapping object for this pull operation.
+ *
+ * @return bool
+ *   FALSE if the queue item should be skipped, and the pull ignored.
+ */
+function hook_salesforce_pull_entity_allowed($drupal_entity_type, $entity_wrapper, $sf_object, $sf_mapping) {
+  if ($drupal_entity_type == 'user' && $entity_wrapper->getIdentifier() == 1) {
+    return FALSE;
+  }
+}
+
+/**
  * Alter a SOQL select query before it is executed. For example, filter
  * target SObjects by a date value, or add an additional field to the query.
  *
