diff --git a/src/bp-core/bp-core-cache.php b/src/bp-core/bp-core-cache.php
index bd73b37af..5cf0d9c07 100644
--- a/src/bp-core/bp-core-cache.php
+++ b/src/bp-core/bp-core-cache.php
@@ -306,6 +306,23 @@ function bp_core_set_incremented_cache( $key, $group, $ids ) {
 	return wp_cache_set( $cache_key, $ids, $group );
 }
 
+/**
+ * Delete a value that has been cached using an incremented key.
+ *
+ * A utility function for use by query methods like BP_Activity_Activity::get().
+ *
+ * @since 3.0.0
+ * @see bp_core_set_incremented_cache()
+ *
+ * @param string $key   Unique key for the query. Usually a SQL string.
+ * @param string $group Cache group. Eg 'bp_activity'.
+ * @return bool True on successful removal, false on failure.
+ */
+function bp_core_delete_incremented_cache( $key, $group ) {
+	$cache_key = bp_core_get_incremented_cache_key( $key, $group );
+	return wp_cache_delete( $cache_key, $group );
+}
+
 /**
  * Gets the key to be used when caching a value using an incremented cache key.
  *
diff --git a/src/bp-friends/bp-friends-cache.php b/src/bp-friends/bp-friends-cache.php
index 819f81796..67081d11e 100644
--- a/src/bp-friends/bp-friends-cache.php
+++ b/src/bp-friends/bp-friends-cache.php
@@ -119,6 +119,19 @@ function bp_friends_clear_request_cache_on_remove( $friendship_id, BP_Friends_Fr
 add_action( 'friends_friendship_withdrawn', 'bp_friends_clear_request_cache_on_remove', 10, 2 );
 add_action( 'friends_friendship_rejected',  'bp_friends_clear_request_cache_on_remove', 10, 2 );
 
+/**
+ * Delete individual friendships from the cache when they are changed.
+ *
+ * @since 3.0.0
+ *
+ * @param BP_Friends_Friendship $friendship Friendship object.
+ */
+function bp_friends_delete_cached_friendships_on_friendship_save( $friendship ) {
+	bp_core_delete_incremented_cache( $friendship->friend_user_id . ':' . $friendship->initiator_user_id, 'bp_friends' );
+	bp_core_delete_incremented_cache( $friendship->initiator_user_id . ':' . $friendship->friend_user_id, 'bp_friends' );
+}
+add_action( 'friends_friendship_after_save', 'bp_friends_delete_cached_friendships_on_friendship_save' );
+
 // List actions to clear super cached pages on, if super cache is installed.
 add_action( 'friends_friendship_rejected',  'bp_core_clear_cache' );
 add_action( 'friends_friendship_accepted',  'bp_core_clear_cache' );
diff --git a/src/bp-friends/bp-friends-filters.php b/src/bp-friends/bp-friends-filters.php
index 9513b4760..cd8ffb04e 100644
--- a/src/bp-friends/bp-friends-filters.php
+++ b/src/bp-friends/bp-friends-filters.php
@@ -34,6 +34,9 @@ function bp_friends_filter_user_query_populate_extras( BP_User_Query $user_query
 
 	$maybe_friend_ids = wp_parse_id_list( $user_ids_sql );
 
+	// Bulk prepare the friendship cache.
+	BP_Friends_Friendship::warm_friendship_cache( $user_id, $maybe_friend_ids );
+
 	foreach ( $maybe_friend_ids as $friend_id ) {
 		$status = BP_Friends_Friendship::check_is_friend( $user_id, $friend_id );
 		$user_query->results[ $friend_id ]->friendship_status = $status;
diff --git a/src/bp-friends/classes/class-bp-friends-friendship.php b/src/bp-friends/classes/class-bp-friends-friendship.php
index f683214e5..195b678a8 100644
--- a/src/bp-friends/classes/class-bp-friends-friendship.php
+++ b/src/bp-friends/classes/class-bp-friends-friendship.php
@@ -603,28 +603,68 @@ class BP_Friends_Friendship {
 			return 'not_friends';
 		}
 
-		/*
-		 * Find friendships where the possible_friend_userid is the
-		 * initiator or friend.
-		 */
-		$args = array(
-			'initiator_user_id' => $possible_friend_userid,
-			'friend_user_id'    => $possible_friend_userid
-		);
-		$result = self::get_friendships( $initiator_userid, $args, 'OR' );
+		BP_Friends_Friendship::warm_friendship_cache( $initiator_userid, $possible_friend_userid );
 
-		if ( $result ) {
-			$friendship = current( $result );
-			if ( ! $friendship->is_confirmed ) {
-				$status = $initiator_userid == $friendship->initiator_user_id ? 'pending' : 'awaiting_response';
+		return bp_core_get_incremented_cache( $initiator_userid . ':' . $possible_friend_userid, 'bp_friends' );
+	}
+
+
+	/**
+	 * Find uncached friendships between a user and one or more other users and cache them.
+	 *
+	 * @since 3.0.0
+	 *
+	 * @param int $user_id                          The ID of the primary user for whom we want 
+	 *                                              to check friendships statuses.
+	 * @param int|array|string $possible_friend_ids The IDs of the one or more users 
+	 *                                              to check friendship status with primary user.
+	 * @return null
+	 */
+	public static function warm_friendship_cache( $user_id, $possible_friend_ids ) {
+		global $wpdb;
+		$bp = buddypress();
+		$possible_friend_ids = wp_parse_id_list( $possible_friend_ids );
+
+		$fetch = array();
+		foreach ( $possible_friend_ids as $friend_id ) {
+			// Check for cached items in both friendship directions.
+			if ( false === bp_core_get_incremented_cache( $user_id . ':' . $friend_id, 'bp_friends' ) 
+				|| false === bp_core_get_incremented_cache( $friend_id . ':' . $user_id, 'bp_friends' ) ) {
+				$fetch[] = $friend_id;
+			}
+		}
+		if ( empty( $fetch ) ) {
+			return;
+		}
+
+		$friend_ids_sql = implode( ',', array_unique( $fetch ) );
+		$sql = $wpdb->prepare( "SELECT initiator_user_id, friend_user_id, is_confirmed FROM {$bp->friends->table_name} WHERE (initiator_user_id = %d AND friend_user_id IN ({$friend_ids_sql}) ) OR (initiator_user_id IN ({$friend_ids_sql}) AND friend_user_id = %d )", $user_id, $user_id );
+		$friendships = $wpdb->get_results( $sql );
+
+		// Use $handled to keep track of all of the $possible_friend_ids we've matched.
+		$handled = array();
+		foreach ( $friendships as $friendship ) {
+			$initiator_user_id = (int) $friendship->initiator_user_id;
+			$friend_user_id    = (int) $friendship->friend_user_id;
+			if ( 1 === (int) $friendship->is_confirmed ) {
+				$status_initiator = $status_friend = 'is_friend';
 			} else {
-				$status = 'is_friend';
+				$status_initiator = 'pending'; 
+				$status_friend    = 'awaiting_response';
 			}
-		} else {
-			$status = 'not_friends';
+			bp_core_set_incremented_cache( $initiator_user_id . ':' . $friend_user_id, 'bp_friends', $status_initiator );
+			bp_core_set_incremented_cache( $friend_user_id . ':' . $initiator_user_id, 'bp_friends', $status_friend );
+
+			$handled[] = ( $initiator_user_id === $user_id ) ? $friend_user_id : $initiator_user_id;
 		}
 
-		return $status;
+		// Set all those with no matching entry to "not friends" status.
+		$not_friends = array_diff( $fetch, $handled );
+
+		foreach ( $not_friends as $not_friend_id ) {
+			bp_core_set_incremented_cache( $user_id . ':' . $not_friend_id, 'bp_friends', 'not_friends' );
+			bp_core_set_incremented_cache( $not_friend_id . ':' . $user_id, 'bp_friends', 'not_friends' );
+		}
 	}
 
 	/**
diff --git a/tests/phpunit/testcases/friends/functions.php b/tests/phpunit/testcases/friends/functions.php
index 2a9209090..a6f9eaa44 100644
--- a/tests/phpunit/testcases/friends/functions.php
+++ b/tests/phpunit/testcases/friends/functions.php
@@ -279,33 +279,6 @@ class BP_Tests_Friends_Functions extends BP_UnitTestCase {
 		return $value;
 	}
 
-	/**
-	 * @group friendship_caching
-	 */
-	public function test_friends_check_friendship_should_hit_user_cache() {
-		global $wpdb;
-		$now = time();
-		$u1 = self::factory()->user->create( array(
-			'last_activity' => date( 'Y-m-d H:i:s', $now ),
-		) );
-		$u2 = self::factory()->user->create( array(
-			'last_activity' => date( 'Y-m-d H:i:s', $now - 100 ),
-		) );
-		$u3 = self::factory()->user->create( array(
-			'last_activity' => date( 'Y-m-d H:i:s', $now - 200 ),
-		) );
-
-		friends_add_friend( $u1, $u2, true );
-		friends_add_friend( $u1, $u3, false );
-
-		friends_check_friendship_status( $u1, $u2 );
-		$first_query_count = $wpdb->num_queries;
-
-		friends_check_friendship_status( $u1, $u3 );
-
-		$this->assertEquals( $first_query_count, $wpdb->num_queries );
-	}
-
 	/**
 	 * @group friendship_caching
 	 */
@@ -325,12 +298,11 @@ class BP_Tests_Friends_Functions extends BP_UnitTestCase {
 		$first_query_count = $wpdb->num_queries;
 
 		/*
-		 * We expect this to generate one query to find $u2's friendships,
-		 * but the friendship object itself should come from cache.
+		 * This should access the previous friendship check's cached items.
 		 */
 		friends_check_friendship_status( $u2, $u1 );
 
-		$this->assertEquals( $first_query_count + 1, $wpdb->num_queries );
+		$this->assertEquals( $first_query_count, $wpdb->num_queries );
 	}
 
 	public function test_friends_get_recently_active() {
