diff --git a/src/agent.c b/src/agent.c
index 5542f2c2c5dc866ef8df4818eec1f2b3c76751dd..3b3b85aa5d6b4ae51a127a5a23f356b7573cd22e 100644
--- a/src/agent.c
+++ b/src/agent.c
@@ -1065,12 +1065,23 @@ static int steer_sta_legacy(struct sta *s)
 	return 0;
 }
 
+/* Translate internal 'pref_neighbor' to wifi's 'nbr' struct */
+void agent_pref_neighbor_to_nbr(struct pref_neighbor *pref_nbr_src,
+		struct nbr *wifi_nbr_dst)
+{
+	memcpy(wifi_nbr_dst->bssid, pref_nbr_src->bssid, 6);
+	wifi_nbr_dst->bssid_info = pref_nbr_src->bssid_info;
+	wifi_nbr_dst->reg = pref_nbr_src->reg;
+	wifi_nbr_dst->channel = pref_nbr_src->channel;
+	wifi_nbr_dst->phy = pref_nbr_src->phy;
+}
+
 static int steer_sta(struct sta *s, struct pref_neighbor *pref_nbr)
 {
 	struct netif_fh *vif = s->vif;
 	struct agent *a = vif->agent;
-	struct pref_neighbor *wifi_nbr_el;
-	struct nbr pref_nbr_el = {};
+	struct pref_neighbor *pref_nbr_el;
+	struct nbr wifi_nbr_el = {};
 	int ret = 0;
 
 	s->steer_secs++;
@@ -1078,7 +1089,7 @@ static int steer_sta(struct sta *s, struct pref_neighbor *pref_nbr)
 				MAC2STR(s->macaddr), s->steer_secs);
 
 	if (pref_nbr) {
-		wifi_nbr_el = pref_nbr;
+		pref_nbr_el = pref_nbr;
 	} else {
 		if (list_empty(&s->pref_nbrlist)) {
 			trace("No better BSS for STA " MACFMT " found\n",
@@ -1086,21 +1097,17 @@ static int steer_sta(struct sta *s, struct pref_neighbor *pref_nbr)
 			return 0;
 		}
 
-		wifi_nbr_el = list_first_entry(&s->pref_nbrlist,
+		pref_nbr_el = list_first_entry(&s->pref_nbrlist,
 						struct pref_neighbor, list);
 	}
 
-	if (!wifi_nbr_el) {
-		warn("Unexpected! wifi_nbr_el is NULL or empty!\n");
+	if (!pref_nbr_el) {
+		warn("Unexpected! pref_nbr_el is NULL or empty!\n");
 		return -1;
 	}
 
 	/* Translate internal 'pref_neighbor' to wifi's 'nbr' struct */
-	memcpy(pref_nbr_el.bssid, wifi_nbr_el->bssid, 6);
-	pref_nbr_el.bssid_info = wifi_nbr_el->bssid_info;
-	pref_nbr_el.reg = wifi_nbr_el->reg;
-	pref_nbr_el.channel = wifi_nbr_el->channel;
-	pref_nbr_el.phy = wifi_nbr_el->phy;
+	agent_pref_neighbor_to_nbr(pref_nbr_el, &wifi_nbr_el);
 
 	/* btm steer ? */
 	if (!s->steer_btm_cnt) {
@@ -1108,10 +1115,10 @@ static int steer_sta(struct sta *s, struct pref_neighbor *pref_nbr)
 		info("Try {%d} to BTM Steer " MACFMT " =======>\n",
 				s->steer_btm_cnt, MAC2STR(s->macaddr));
 
-		ret = wifi_req_bss_transition(vif->name, s->macaddr, 1, &pref_nbr_el, 0);
+		ret = wifi_req_bss_transition(vif->name, s->macaddr, 1, &wifi_nbr_el, 0);
 		if (!ret) {
 			wifiagent_log_steer(a, s->macaddr, vif->name,
-					"steer_btmreq", pref_nbr_el.bssid);
+					"steer_btmreq", wifi_nbr_el.bssid);
 		} else  {
 			warn("Failed to send BTM request to " MACFMT "\n",
 					MAC2STR(s->macaddr));
@@ -1130,10 +1137,10 @@ static int steer_sta(struct sta *s, struct pref_neighbor *pref_nbr)
 					s->steer_btm_cnt, MAC2STR(s->macaddr));
 
 			ret = wifi_req_bss_transition(vif->name, s->macaddr,
-						1, &pref_nbr_el, 0);
+						1, &wifi_nbr_el, 0);
 			if (!ret)
 				wifiagent_log_steer(a, s->macaddr, vif->name,
-						"steer_btmreq", pref_nbr_el.bssid);
+						"steer_btmreq", wifi_nbr_el.bssid);
 			else
 				warn("Failed to send BTM request to " MACFMT "\n",
 						MAC2STR(s->macaddr));
@@ -7007,7 +7014,7 @@ int wifiagent_steer_sta(struct ubus_context *ctx,
 {
 	struct agent *a = this_agent;
 	struct sta *s;
-	struct nbr *pref_nbr_list = NULL;
+	struct nbr *wifi_nbr_list = NULL;
 	int i;
 	int ret = 0;
 
@@ -7047,25 +7054,21 @@ int wifiagent_steer_sta(struct ubus_context *ctx,
 	}
 
 	/* Translate internal 'pref_neighbor' to wifi's 'nbr' struct */
-	pref_nbr_list = calloc(prefcnt, sizeof(struct nbr));
-	if (WARN_ON(!pref_nbr_list))
+	wifi_nbr_list = calloc(prefcnt, sizeof(struct nbr));
+	if (WARN_ON(!wifi_nbr_list))
 		return -ENOMEM;
 
 	for (i = 0; i < prefcnt; i++) {
-		memcpy(pref_nbr_list[i].bssid, pref[i].bssid, 6);
-		pref_nbr_list[i].bssid_info = pref[i].bssid_info;
-		pref_nbr_list[i].reg = pref[i].reg;
-		pref_nbr_list[i].channel = pref[i].channel;
-		pref_nbr_list[i].phy = pref[i].phy;
+		agent_pref_neighbor_to_nbr(&pref[i], &wifi_nbr_list[i]);
 	}
 
-	ret = wifi_req_bss_transition(ifname, s->macaddr, prefcnt, pref_nbr_list, 0);
+	ret = wifi_req_bss_transition(ifname, s->macaddr, prefcnt, wifi_nbr_list, 0);
 
 	if (ret)
 		dbg("Failed to send BTM request to " MACFMT "\n",
 		    MAC2STR(s->macaddr));
 
-	free(pref_nbr_list);
+	free(wifi_nbr_list);
 
 	return ret;
 }
diff --git a/src/agent.h b/src/agent.h
index 7bc09e57f9d4debef57e10901767fecd3804cfbc..5eb77567877f0479d09fa5aafa26a9b947402daf 100644
--- a/src/agent.h
+++ b/src/agent.h
@@ -905,5 +905,7 @@ struct netif_wds *netif_alloc_wds(struct agent *a, const char *ifname);
 void netif_free_wds(struct netif_wds *n);
 void netif_free_wds_by_ifname(struct agent *a, const char *ifname);
 struct netif_wds *find_wds_by_ifname(struct agent *a, const char *ifname);
+void agent_pref_neighbor_to_nbr(struct pref_neighbor *pref_nbr_src,
+		struct nbr *wifi_nbr_dst);
 
 #endif /* AGENT_H */
diff --git a/src/agent_map.c b/src/agent_map.c
index 6bc16308abf9958aed6b2c4e68db79031cb700ab..e2cf04f90da363da4d405e809959ad949f2b7bae 100644
--- a/src/agent_map.c
+++ b/src/agent_map.c
@@ -3822,7 +3822,7 @@ int agent_send_request_transition(void *agent, uint8_t *client_sta,
  * & channel utilization.
  */
 int agent_find_best_bssid_for_sta(struct agent *a, uint8_t *sta, uint8_t *src_bssid,
-		uint8_t *out_bssid)
+		struct pref_neighbor *best_target)
 {
 	struct netif_fh *p;
 	int ret = 0;
@@ -3835,11 +3835,11 @@ int agent_find_best_bssid_for_sta(struct agent *a, uint8_t *sta, uint8_t *src_bs
 		/* FIXME: using first non-self fh bssid */
 		ret = memcmp(src_bssid, p->bssid, 6);
 		if (ret != 0) {
-			memcpy(out_bssid, p->bssid, 6);
+			memcpy(best_target->bssid, p->bssid, 6);
 			return 0;
 		}
 	}
-	memcpy(out_bssid, src_bssid, 6);
+	memcpy(best_target->bssid, src_bssid, 6);
 	return 0;
 }
 
@@ -4165,17 +4165,20 @@ static int agent_sta_disallowed(struct agent *a,
 }
 
 static int agent_try_steer_sta(struct agent *a, struct netif_fh *fh,
-		uint8_t *src_bssid, uint8_t *sta_mac, uint8_t *dst_bssid,
+		uint8_t *src_bssid, uint8_t *sta_mac, struct pref_neighbor *pref_target,
 		struct sta_error_response *sta_resp, int count, uint8_t req_mode)
 {
 	trace("agent: %s: --->\n", __func__);
 
-	uint8_t target_bssid[6] = { 0 };
+	struct pref_neighbor target = {};
 	int ret = 0;
 	int i;
 
 	dbg("steered STA mac: " MACFMT "\n", MAC2STR(sta_mac));
-	dbg("target bssid: " MACFMT "\n", MAC2STR(dst_bssid));
+	if (pref_target)
+		dbg("target bssid: " MACFMT "\n", MAC2STR(pref_target->bssid));
+	else
+		dbg("target bssid unspecified!\n");
 
 	/* Check if STA is allowed for steering */
 	ret = agent_sta_disallowed(a, sta_mac, STA_DISALLOWED_LOCAL);
@@ -4195,23 +4198,22 @@ static int agent_try_steer_sta(struct agent *a, struct netif_fh *fh,
 			return -1;
 	}
 
-	/* Calculate target bssid for this STA */
-	if (is_wildcard_bssid(dst_bssid))
-		ret = agent_find_best_bssid_for_sta(a, sta_mac, src_bssid, target_bssid);
-	else
-		memcpy(target_bssid, dst_bssid, 6);
-
-	if (ret)
-		return -1;
+	if (pref_target && !is_wildcard_bssid(pref_target->bssid))
+		/* Target specified directly in Steering Request TLV */
+		memcpy(&target, pref_target, sizeof(struct pref_neighbor));
+	else {
+		/* Best target BSSID for this STA has to be found */
+		ret = agent_find_best_bssid_for_sta(a, sta_mac, src_bssid, &target);
+		if (ret)
+			return -1;
+	}
 
 	/* Check if STA is disallowed from BTM steering */
 	ret = agent_sta_disallowed(a, sta_mac, STA_DISALLOWED_BTM);
 	if (!ret) {
-		struct nbr pref;
-
-		memcpy(pref.bssid, target_bssid, 6);
+		struct nbr pref = {};
 
-		/* TODO: pref.channel & pref.reg from controller */
+		agent_pref_neighbor_to_nbr(&target, &pref);
 
 		/* BTM steering */
 		ret = agent_send_request_transition(a, sta_mac, fh, &pref, 0);
@@ -4224,7 +4226,7 @@ static int agent_try_steer_sta(struct agent *a, struct netif_fh *fh,
 					",\"dst_bssid\":\""MACFMT"\"}",
 					MAC2STR(sta_mac),
 					MAC2STR(src_bssid),
-					MAC2STR(target_bssid));
+					MAC2STR(target.bssid));
 
 			agent_notify_iface_event(a, fh->name, "request_btm", ev_data);
 		}
@@ -4251,7 +4253,6 @@ int agent_process_steer_request_tlv(void *agent,
 	struct sta *s;
 	struct sta_error_response sta_resp[MAX_STA];
 	uint32_t count = 0;
-	uint8_t wildcard[6] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
 	uint8_t mode = 0x00;
 	uint8_t req_mode = 0x00;
 	uint16_t op_window;
@@ -4259,11 +4260,7 @@ int agent_process_steer_request_tlv(void *agent,
 	uint8_t num_sta;
 	uint8_t *stalist = NULL;
 	uint8_t num_bss;
-	struct bss_data{
-		uint8_t bssid[6];
-		uint8_t opclass;
-		uint8_t channel;
-	} *barray = NULL;
+	struct pref_neighbor *pref_arr = NULL;
 	uint8_t *data = (uint8_t *)p;
 
 	memcpy(bssid, &data[offset], 6);
@@ -4348,8 +4345,8 @@ int agent_process_steer_request_tlv(void *agent,
 	}
 
 	if (num_bss > 0) {
-		barray = calloc(num_bss, sizeof(struct bss_data));
-		if (!barray) {
+		pref_arr = calloc(num_bss, sizeof(struct pref_neighbor));
+		if (!pref_arr) {
 			dbg("%s:%d -ENOMEM\n", __func__, __LINE__);
 			ret = -1;
 			goto out;
@@ -4357,10 +4354,14 @@ int agent_process_steer_request_tlv(void *agent,
 	}
 
 	for (i = 0; i < num_bss; i++) {
-		memcpy(barray[i].bssid, &data[offset], 6);
+		memcpy(pref_arr[i].bssid, &data[offset], 6);
 		offset += 6;
-		barray[i].opclass = data[offset++];
-		barray[i].channel = data[offset++];
+		/* Target BSS Operating Class */
+		pref_arr[i].reg = data[offset++];
+		/* Target BSS Channel Number for channel on which
+		 * the Target BSS is transmitting Beacon frames.
+		 */
+		pref_arr[i].channel = data[offset++];
 	}
 
 	/* Check src bssid present */
@@ -4386,7 +4387,7 @@ int agent_process_steer_request_tlv(void *agent,
 			list_for_each_entry(s, &fh->stalist, list) {
 				/* Call for transition of sta */
 				ret = agent_try_steer_sta(a, fh, bssid,
-						s->macaddr, barray[0].bssid,
+						s->macaddr, &pref_arr[0],
 						sta_resp, count, req_mode);
 				if (ret)
 					dbg("[%s:%d] Couldn't steer " MACFMT "\n",
@@ -4415,7 +4416,7 @@ int agent_process_steer_request_tlv(void *agent,
 		for (i = 0; i < num_sta; i++) {
 			/* Call for transition of sta */
 			ret = agent_try_steer_sta(a, fh, bssid,
-					&stalist[i * 6], barray[i].bssid,
+					&stalist[i * 6], &pref_arr[i],
 					sta_resp, count, req_mode);
 		}
 	}
@@ -4425,7 +4426,7 @@ int agent_process_steer_request_tlv(void *agent,
 		for (i = 0; i < num_sta; i++) {
 			/* Call for transition of sta */
 			ret = agent_try_steer_sta(a, fh, bssid,
-					&stalist[i * 6], barray[0].bssid,
+					&stalist[i * 6], &pref_arr[0],
 					sta_resp, count, req_mode);
 		}
 	}
@@ -4435,7 +4436,7 @@ int agent_process_steer_request_tlv(void *agent,
 		for (i = 0; i < num_sta; i++) {
 			/* Call for transition of sta */
 			ret = agent_try_steer_sta(a, fh, bssid,
-					&stalist[i * 6], wildcard,
+					&stalist[i * 6], NULL,
 					sta_resp, count, req_mode);
 		}
 	/* Unspecified error condition */
@@ -4452,8 +4453,8 @@ out:
 	if (stalist)
 		free(stalist);
 
-	if (barray)
-		free(barray);
+	if (pref_arr)
+		free(pref_arr);
 
 	return ret;
 }
diff --git a/src/wifi_ubus.c b/src/wifi_ubus.c
index 9bab4b45d457f663ea34eaa11b8f442b6d12e8b6..f6c3e1c638926298467b72d673e10989100d57da 100644
--- a/src/wifi_ubus.c
+++ b/src/wifi_ubus.c
@@ -930,14 +930,32 @@ int wifi_ubus_request_transition(struct ubus_context *ubus_ctx, const char *ifna
 		goto out;
 
 	blob_buf_init(&bb, 0);
+	/* Client STA MAC addr */
 	blobmsg_add_string(&bb, "sta", macstr);
+	/* Target params: bssid, bssid_info, reg, channel & phy */
 	t = blobmsg_open_array(&bb, "target_ap");
+
 	for (i = 0; i < pref_num; i++) {
 		void *tt;
 
 		tt = blobmsg_open_table(&bb, "");
+
+		/* skip if bssid is not provided */
+		if (hwaddr_is_zero(pref[i].bssid))
+			continue;
+
 		hwaddr_ntoa(pref[i].bssid, macstr);
 		blobmsg_add_string(&bb, "bssid", macstr);
+		/* optional */
+		if (pref[i].bssid_info)
+			blobmsg_add_u32(&bb, "bssid_info", pref[i].bssid_info);
+		if (pref[i].reg)
+			blobmsg_add_u32(&bb, "reg", pref[i].reg);
+		if (pref[i].channel)
+			blobmsg_add_u32(&bb, "channel", pref[i].channel);
+		if (pref[i].phy)
+			blobmsg_add_u32(&bb, "phy", pref[i].phy);
+
 		blobmsg_close_table(&bb, tt);
 	}
 	blobmsg_close_array(&bb, t);