diff --git src/bp-members/bp-members-functions.php src/bp-members/bp-members-functions.php
index c55e942c6..7ea06d83b 100644
--- src/bp-members/bp-members-functions.php
+++ src/bp-members/bp-members-functions.php
@@ -3027,6 +3027,44 @@ function bp_set_member_type( $user_id, $member_type, $append = false ) {
 	return $retval;
 }
 
+/**
+ * Set types for a member.
+ *
+ * @since 2.2.0
+ *
+ * @param int   $user_id     ID of the user.
+ * @param array $member_types Member type.
+ * @param bool  $append      Optional. True to append this to existing types for user,
+ *                            false to replace. Default: false.
+ * @return false|array $retval See {@see bp_set_object_terms()}.
+ */
+function bp_set_member_types( $user_id, $member_types, $append = false ) {
+	// Pass an empty $member_type to remove a user's type.
+	if ( ! empty( $member_type ) && ! is_array( $member_types ) ) {
+		return false;
+	}
+
+	$retval = bp_set_object_terms( $user_id, $member_types, bp_get_member_type_tax_name(), $append );
+
+	// Bust the cache if the type has been updated.
+	if ( ! is_wp_error( $retval ) ) {
+		wp_cache_delete( $user_id, 'bp_member_member_types' );
+
+		/**
+		 * Fires just after a user's member type has been changed.
+		 *
+		 * @since 2.2.0
+		 *
+		 * @param int    $user_id     ID of the user whose member type has been updated.
+		 * @param string $member_type Member type.
+		 * @param bool   $append      Whether the type is being appended to existing types.
+		 */
+		do_action( 'bp_set_member_types', $user_id, $member_types, $append );
+	}
+
+	return $retval;
+}
+
 /**
  * Remove type for a member.
  *
diff --git src/bp-members/classes/class-bp-members-admin.php src/bp-members/classes/class-bp-members-admin.php
index d344b5d7c..0503c0c41 100644
--- src/bp-members/classes/class-bp-members-admin.php
+++ src/bp-members/classes/class-bp-members-admin.php
@@ -1286,62 +1286,77 @@ class BP_Members_Admin {
 			return;
 		}
 
-		$types = bp_get_member_types( array(), 'objects' );
-		$current_type = bp_get_member_type( $user->ID );
-		?>
-
-		<label for="bp-members-profile-member-type" class="screen-reader-text"><?php
+			$types         = bp_get_member_types( array(), 'object' );
+			$current_types = bp_get_member_type( $user->ID, false );
+			$selected      = '';
+			?>
+		<label for="bp-members-profile-member-type" class="screen-reader-text">
+			<?php
 			/* translators: accessibility text */
 			esc_html_e( 'Select member type', 'buddypress' );
-		?></label>
-		<select name="bp-members-profile-member-type" id="bp-members-profile-member-type">
-			<option value="" <?php selected( '', $current_type ); ?>><?php
-				/* translators: no option picked in select box */
-				esc_attr_e( '----', 'buddypress' );
-			?></option>
+			?>
+		</label>
+
+		<select name="bp-members-profile-member-type[]" id="bp-members-profile-member-type" multiple="multiple">
+			<option value=""><?php
+
+					/* translators: no option picked in select box */
+					esc_attr_e( '----', 'buddypress' );
+					?>
+			</option>
 			<?php foreach ( $types as $type ) : ?>
-				<option value="<?php echo esc_attr( $type->name ) ?>" <?php selected( $type->name, $current_type ) ?>><?php echo esc_html( $type->labels['singular_name'] ) ?></option>
+				<?php
+				if ( ! empty( $current_types ) && in_array( $type->name, $current_types ) ) {
+					$selected = 'selected';
+				} else {
+					$selected = '';
+				}
+				?>
+				<option value="<?php echo esc_attr( $type->name ); ?> "<?php echo esc_attr( $selected ); ?>><?php echo esc_html( $type->labels['singular_name'] ); ?></option>
 			<?php endforeach; ?>
 		</select>
-
-		<?php
-
-		wp_nonce_field( 'bp-member-type-change-' . $user->ID, 'bp-member-type-nonce' );
-	}
-
-	/**
-	 * Process changes from the Member Type metabox.
-	 *
-	 * @since 2.2.0
-	 */
-	public function process_member_type_update() {
-		if ( ! isset( $_POST['bp-member-type-nonce'] ) || ! isset( $_POST['bp-members-profile-member-type'] ) ) {
-			return;
+			<?php
+				wp_nonce_field( 'bp-member-type-change-' . $user->ID, 'bp-member-type-nonce' );
 		}
 
-		$user_id = $this->get_user_id();
+		/**
+		 * Process changes from the Member Type metabox.
+		 *
+		 * @since 2.2.0
+		 */
+		public function process_member_type_update() {
+			if ( ! isset( $_POST['bp-member-type-nonce'] ) || ! isset( $_POST['bp-members-profile-member-type'] ) ) {
+					return;
+			}
 
-		check_admin_referer( 'bp-member-type-change-' . $user_id, 'bp-member-type-nonce' );
+			$user_id      = $this->get_user_id();
+			$member_types = array();
 
-		// Permission check.
-		if ( ! bp_current_user_can( 'bp_moderate' ) && $user_id != bp_loggedin_user_id() ) {
-			return;
-		}
+			check_admin_referer( 'bp-member-type-change-' . $user_id, 'bp-member-type-nonce' );
 
-		// Member type string must either reference a valid member type, or be empty.
-		$member_type = stripslashes( $_POST['bp-members-profile-member-type'] );
-		if ( ! empty( $member_type ) && ! bp_get_member_type_object( $member_type ) ) {
-			return;
-		}
+			// Permission check.
+			if ( ! bp_current_user_can( 'bp_moderate' ) && $user_id != bp_loggedin_user_id() ) {
+				return;
+			}
+			$member_types = wp_unslash( $_POST['bp-members-profile-member-type'] );
+			foreach ( $member_types as $key => $types ) {
+				// Member type string must either reference a valid member type, or be empty.
+				$member_type = stripslashes( $types );
+				if ( ! empty( $member_type ) && ! bp_get_member_type_object( $member_type ) ) {
+					return;
+				}
 
-		/*
-		 * If an invalid member type is passed, someone's doing something
-		 * fishy with the POST request, so we can fail silently.
-		 */
-		if ( bp_set_member_type( $user_id, $member_type ) ) {
-			// @todo Success messages can't be posted because other stuff happens on the page load.
+				$member_types[ $key ] = $member_type;
+			}
+
+			/*
+			 * If an invalid member type is passed, someone's doing something
+			 * fishy with the POST request, so we can fail silently.
+			 */
+			if ( bp_set_member_types( $user_id, $member_types ) ) {
+				// @todo Success messages can't be posted because other stuff happens on the page load.
+			}
 		}
-	}
 
 	/**
 	 * Add a link to Profile in Users listing row actions.
@@ -2470,23 +2485,37 @@ class BP_Members_Admin {
 	 *
 	 * @return string Member type as a link to filter all users.
 	 */
-	public function users_table_populate_type_cell( $retval = '', $column_name = '', $user_id = 0 ) {
-		// Only looking for member type column.
-		if ( bp_get_member_type_tax_name() !== $column_name ) {
-			return $retval;
-		}
+		public function users_table_populate_type_cell( $retval = '', $column_name = '', $user_id = 0 ) {
+			// Only looking for member type column.
+			if ( bp_get_member_type_tax_name() !== $column_name ) {
+				return $retval;
+			}
 
-		// Get the member type.
-		$type = bp_get_member_type( $user_id );
+			// Get the member type.
+			$types = bp_get_member_type( $user_id, false );
 
-		// Output the
-		if ( $type_obj = bp_get_member_type_object( $type ) ) {
-			$url = add_query_arg( array( 'bp-member-type' => urlencode( $type ) ) );
-			$retval = '<a href="' . esc_url( $url ) . '">' . esc_html( $type_obj->labels['singular_name'] ) . '</a>';
-		}
+			if ( ! empty( $types ) ) {
 
-		return $retval;
-	}
+				$member_types = '';
+
+				foreach ( $types as $key => $type ) {
+					if ( $type_obj = bp_get_member_type_object( $type ) ) {
+
+						if ( ! empty( $member_types ) ) {
+							$member_types .= ', ';
+						}
+
+						$url           = add_query_arg( array( 'bp-member-type' => urlencode( $type ) ) );
+						$member_types .= '<a href="' . esc_url( $url ) . '">' . esc_html( $type_obj->labels['name'] ) . '</a>';
+					}
+				}
+
+				if ( ! empty( $member_types ) ) {
+					$retval .= '<br />' . $member_types;
+				}
+				return $retval;
+			}
+		}
 
 	/**
 	 * Filter WP Admin users list table to include users of the specified type.
