diff --git a/common/device-scan.c b/common/device-scan.c
index 00ce15244a09..512754c01adb 100644
--- a/common/device-scan.c
+++ b/common/device-scan.c
@@ -541,6 +541,48 @@ int btrfs_scan_argv_devices(int dev_optind, int dev_argc, char **dev_argv)
 	return 0;
 }
 
+int scan_reunite_fs_devices(char *path)
+{
+	int ret;
+	int fd;
+	u64 total_devs;
+	struct btrfs_fs_devices *fs_devices;
+
+	ret = check_arg_type(path);
+	if (ret != BTRFS_ARG_BLKDEV && ret != BTRFS_ARG_REG) {
+		if (ret < 0) {
+			errno = -ret;
+			error("invalid argument %s: %m", path);
+		} else {
+			error("not a block device or regular file: %s", path);
+		}
+	}
+
+	fd = open(path, O_RDONLY);
+	if (fd < 0) {
+		error("cannot open %s: %m", path);
+		return -errno;
+	}
+	ret = btrfs_scan_one_device(fd, path, &fs_devices, &total_devs,
+				    BTRFS_SUPER_INFO_OFFSET, SBREAD_DEFAULT);
+	close(fd);
+	if (ret < 0) {
+		errno = -ret;
+		error("device scan of %s failed: %m", path);
+		return ret;
+	}
+
+	ret = 0;
+	/* Check for missing device */
+	if (fs_devices->num_devices != total_devs)
+		ret = reunite_fs_devices(fs_devices);
+
+	if (!ret)
+		fs_devices->sanitized = true;
+
+	return ret;
+}
+
 bool array_append(char **dest, char *src, int *cnt)
 {
 	char *this_tok = strtok(src, ",");
diff --git a/common/device-scan.h b/common/device-scan.h
index 7a6874298051..a1193e7f7020 100644
--- a/common/device-scan.h
+++ b/common/device-scan.h
@@ -61,5 +61,6 @@ void free_seen_fsid(struct seen_fsid *seen_fsid_hash[]);
 int test_uuid_unique(const char *uuid_str);
 bool array_append(char **dest, char *src, int *cnt);
 void free_array(char **prt, int cnt);
+int scan_reunite_fs_devices(char *path);
 
 #endif
diff --git a/kernel-shared/volumes.c b/kernel-shared/volumes.c
index ac9e711a994f..642f7084cf63 100644
--- a/kernel-shared/volumes.c
+++ b/kernel-shared/volumes.c
@@ -2958,3 +2958,76 @@ int btrfs_fix_device_and_super_size(struct btrfs_fs_info *fs_info)
 	}
 	return ret;
 }
+
+static int find_unifiable(struct btrfs_fs_devices *fsinfo_fs_devices,
+			  struct btrfs_fs_devices **ret_fs_devices)
+{
+	u8 *orig_uuid = fsinfo_fs_devices->metadata_uuid;
+	u8 *orig_fsid = fsinfo_fs_devices->fsid;
+	struct btrfs_fs_devices *fs_devices = NULL;
+	int ret = 0;
+
+	list_for_each_entry(fs_devices, &fs_uuids, list) {
+		/* skip the same fs_info fsid */
+		if (!memcmp(fs_devices->fsid, orig_fsid, BTRFS_FSID_SIZE))
+			continue;
+
+		/* skip the metadata_uuid which isn't fs_info metadata_uuid */
+		if (memcmp(fs_devices->metadata_uuid, orig_uuid, BTRFS_FSID_SIZE))
+			continue;
+
+		ret++;
+		*ret_fs_devices = fs_devices;
+	}
+
+	return ret;
+}
+
+int reunite_fs_devices(struct btrfs_fs_devices *fs_devices)
+{
+	struct btrfs_fs_devices *other_fs_devices = NULL;
+	struct btrfs_device *tmp_device;
+	struct btrfs_device *device;
+	int other_fsid_cnt = 0;
+	int missing_devs;
+
+	missing_devs = fs_devices->total_devices - fs_devices->num_devices;
+	other_fsid_cnt = find_unifiable(fs_devices, &other_fs_devices);
+
+	if (other_fsid_cnt == 0) {
+		error("No missing device(s) found");
+		return -EINVAL;
+	} else if (other_fsid_cnt > 1) {
+		error("Found more than one fsid with the same metadata_uuid");
+		error("Try use --device and --noscan options");
+		return -EINVAL;
+	}
+
+	/* Missing count in the fs_info should match with the scanned devices */
+	if (missing_devs != other_fs_devices->num_devices) {
+		error("Missing device(s) found %d expected %d",
+		      other_fs_devices->num_devices, missing_devs);
+		return -EINVAL;
+	}
+
+	list_for_each_entry_safe(device, tmp_device, &other_fs_devices->devices,
+				 dev_list) {
+		/* We have found the missing device, bring it in */
+		list_move(&device->dev_list, &fs_devices->devices);
+		fs_devices->num_devices++;
+		missing_devs--;
+	}
+
+	if (!list_empty(&other_fs_devices->devices) || missing_devs != 0 ||
+	    fs_devices->total_devices != fs_devices->num_devices) {
+		error("Found more or fewer missing devices");
+		return -EINVAL;
+	}
+
+	if (other_fs_devices->changing_fsid)
+		fs_devices->changing_fsid = true;
+	if (other_fs_devices->active_metadata_uuid)
+		fs_devices->active_metadata_uuid = true;
+
+	return 0;
+}
diff --git a/kernel-shared/volumes.h b/kernel-shared/volumes.h
index 13d08cc7eea5..9f755dfa9015 100644
--- a/kernel-shared/volumes.h
+++ b/kernel-shared/volumes.h
@@ -104,6 +104,7 @@ struct btrfs_fs_devices {
 
 	bool changing_fsid;
 	bool active_metadata_uuid;
+	bool sanitized;
 };
 
 struct btrfs_bio_stripe {
@@ -318,5 +319,6 @@ int btrfs_bg_type_to_nparity(u64 flags);
 int btrfs_bg_type_to_sub_stripes(u64 flags);
 u64 btrfs_bg_flags_for_device_num(int number);
 bool btrfs_bg_type_is_stripey(u64 flags);
+int reunite_fs_devices(struct btrfs_fs_devices *fs_devices);
 
 #endif
