diff --git a/tools/perf/util/bpf-loader.c b/tools/perf/util/bpf-loader.c
index 023fc12..e185fb6 100644
--- a/tools/perf/util/bpf-loader.c
+++ b/tools/perf/util/bpf-loader.c
@@ -643,6 +643,7 @@ enum bpf_map_priv_key_type {
 
 enum bpf_map_priv_value_type {
 	BPF_MAP_PRIV_VAL_VALUE,
+	BPF_MAP_PRIV_VAL_EVSEL,
 };
 
 struct bpf_map_priv {
@@ -660,6 +661,7 @@ struct bpf_map_priv {
 		enum bpf_map_priv_value_type type;
 		union {
 			u64 val;
+			struct perf_evsel *evsel;
 		};
 	} value;
 };
@@ -715,6 +717,7 @@ bpf_map_config_foreach_key(struct bpf_map *map,
 
 	switch (def.type) {
 	case BPF_MAP_TYPE_ARRAY:
+	case BPF_MAP_TYPE_PERF_EVENT_ARRAY:
 		switch (priv->key.type) {
 		case BPF_MAP_PRIV_KEY_ALL:
 			for (i = 0; i < def.max_entries; i++) {
@@ -838,6 +841,69 @@ bpf__config_obj_map_value(struct bpf_map *map,
 	return -EINVAL;
 }
 
+static int
+bpf__config_obj_map_array_event(struct bpf_map *map,
+				struct parse_events_term *term,
+				struct perf_evlist *evlist)
+{
+	struct bpf_map_priv *priv;
+	struct perf_evsel *evsel;
+	struct bpf_map_def def;
+	const char *map_name;
+	int err;
+
+	map_name = bpf_map__get_name(map);
+	evsel = perf_evlist__find_evsel_by_alias(evlist, term->val.str);
+	if (!evsel) {
+		pr_debug("Event (for '%s') '%s' doesn't exist\n",
+			 map_name, term->val.str);
+		return -EINVAL;
+	}
+
+	err = bpf_map__get_def(map, &def);
+	if (err) {
+		pr_debug("Unable to get map definition from '%s'\n",
+			 map_name);
+		return -EINVAL;
+	}
+	
+	/*
+	 * No need to check key_size and value_size:
+	 * kernel has already checked them.
+	 */
+	if (def.type != BPF_MAP_TYPE_PERF_EVENT_ARRAY) {
+		pr_debug("Map %s type is not BPF_MAP_TYPE_PERF_EVENT_ARRAY\n",
+			 map_name);
+		return -EINVAL;
+	}
+
+	priv = zalloc(sizeof(*priv));
+	if (!priv) {
+		pr_debug("No enough memory for map private\n");
+		return -ENOMEM;
+	}
+
+	err = bpf_map_priv_setkey(priv, term, map_name);
+	if (err)
+		return err;
+
+	priv->value.type = BPF_MAP_PRIV_VAL_EVSEL;
+	priv->value.evsel = evsel;
+	return bpf_map__set_private(map, priv, bpf_map_priv__clear);
+}
+
+static int
+bpf__config_obj_map_event(struct bpf_map *map,
+			  struct parse_events_term *term,
+			  struct perf_evlist *evlist)
+{
+	if (term->type_val == PARSE_EVENTS__TERM_TYPE_STR)
+		return bpf__config_obj_map_array_event(map, term, evlist);
+
+	pr_debug("ERROR: wrong value type\n");
+	return -EINVAL;
+}
+
 struct bpf_config_map_func {
 	const char *config_opt;
 	int (*config_func)(struct bpf_map *, struct parse_events_term *,
@@ -846,6 +912,7 @@ struct bpf_config_map_func {
 
 struct bpf_config_map_func bpf_config_map_funcs[] = {
 	{"value", bpf__config_obj_map_value},
+	{"event", bpf__config_obj_map_event},
 };
 
 static int
@@ -964,6 +1031,40 @@ bpf__apply_config_value_for_key(int map_fd, void *pkey,
 }
 
 static int
+bpf__apply_config_evsel_for_key(const char *name, int map_fd, void *pkey,
+				struct perf_evsel *evsel)
+{
+	struct xyarray *xy = evsel->fd;
+	unsigned int key, events;
+	int *evt_fd;
+	int err;
+
+	if (!xy) {
+		pr_debug("ERROR: evsel not ready for map %s\n", name);
+		return -EINVAL;
+	}
+
+	if (xy->row_size / xy->entry_size != 1) {
+		pr_debug("ERROR: Dimension of target event is incorrect for map %s\n",
+			 name);
+		return -EINVAL;
+	}
+
+	events = xy->entries / (xy->row_size / xy->entry_size);
+	key = *((unsigned int *)pkey);
+	if (key >= events) {
+		pr_debug("ERROR: there is no event %d for map %s\n",
+			 key, name);
+		return -E2BIG;
+	}
+	evt_fd = xyarray__entry(xy, key, 0);
+	err = bpf_map_update_elem(map_fd, pkey, evt_fd, BPF_ANY);
+	if (err && errno)
+		err = -errno;
+	return err;
+}
+
+static int
 bpf__apply_config_map_for_key(const char *name, int map_fd,
 			      struct bpf_map_def *pdef __maybe_unused,
 			      struct bpf_map_priv *priv,
@@ -977,6 +1078,10 @@ bpf__apply_config_map_for_key(const char *name, int map_fd,
 						      pdef->value_size,
 						      priv->value.val);
 		break;
+	case BPF_MAP_PRIV_VAL_EVSEL:
+		err = bpf__apply_config_evsel_for_key(name, map_fd, pkey,
+						      priv->value.evsel);
+		break;
 	default:
 		pr_debug("ERROR: unknown value type for '%s'\n", name);
 		err = -EINVAL;
@@ -1081,6 +1186,7 @@ int bpf__strerror_apply_config(int err, char *buf, size_t size)
 {
 	bpf__strerror_head(err, buf, size);
 	bpf__strerror_entry(EINVAL, "Invalid option for map, add -v to see detail");
+	bpf__strerror_entry(E2BIG,  "Array index too big, add -v to see detail");
 	bpf__strerror_end(buf, size);
 	return 0;
 }
diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c
index a2af5a8..ae973cd 100644
--- a/tools/perf/util/parse-events.c
+++ b/tools/perf/util/parse-events.c
@@ -654,7 +654,7 @@ parse_events_config_bpf(struct parse_events_evlist *data,
 						 err, errbuf, sizeof(errbuf));
 			data->error->help = strdup(
 "Hint:\tValid config term:\n"
-"     \tmaps.<mapname>.value<indics>\n"
+"     \tmaps.<mapname>.[value|event]<indics>\n"
 "\n"
 "     \twhere <indics> is something like [0,3-4]\n"
 "     \t(add -v to see detail)");
