diff --git a/README.md b/README.md
index 7025b2b..58a6e8e 100644
--- a/README.md
+++ b/README.md
@@ -226,6 +226,27 @@ _ := reflections.SetField(&s, "FirstField", "new value")
 err := reflection.SetField(&s, "FirstField", 123) // err != nil
 ```
 
+##### GetFieldNameByTagValue
+
+*GetFieldNameByTagValue* looks up a field with a matching `{tagKey}:"{tagValue}"` tag in the provided `obj` item.
+If `obj` is not a `struct`, nor a `pointer`, or it does not have a field tagged with the `tagKey`, and the matching `tagValue`, this function returns an error. 
+
+```go
+    s := MyStruct {
+        FirstField: "first value",      `matched:"first tag"`
+        SecondField: 2,                 `matched:"second tag"`
+        ThirdField: "third value",      `unmatched:"third tag"`
+    }
+
+    // Getting field name from external source as json would be a headache to convert it manually, 
+    // so we get it directly from struct tag
+    // returns fieldName = "FirstField"
+    fieldName, _ = reflections.GetFieldNameByTagValue(s, "first tag", "matched");
+
+    // later we can do GetField(s, fieldName)
+```
+
+
 ## Important notes
 
 - **un-exported fields** can't be accessed nor set using the `reflections` library. The Go lang standard `reflect` library intentionally prohibits un-exported fields values access or modifications.
diff --git a/example_test.go b/example_test.go
index c715b43..2030854 100644
--- a/example_test.go
+++ b/example_test.go
@@ -1,6 +1,7 @@
 package reflections_test
 
 import (
+	"encoding/json"
 	"fmt"
 	"log"
 	"reflect"
@@ -213,3 +214,51 @@ func ExampleSetField() {
 		log.Fatal(err)
 	}
 }
+
+func ExampleGetFieldNameByTagValue() {
+	type Order struct {
+		Step     string `json:"order_step"`
+		ID       string `json:"id"`
+		Category string `json:"category"`
+	}
+	type Condition struct {
+		Field string `json:"field"`
+		Value string `json:"value"`
+		Next  string `json:"next"`
+	}
+
+	// JSON data from external source
+	orderJSON := `{
+		"order_step": "cooking",
+		"id": "45457-fv54f54",
+		"category": "Pizzas"
+	}`
+
+	conditionJSON := `{
+		"field": "order_step", 
+		"value": "cooking",
+		"next": "serve"
+	}`
+
+	// Storing JSON in corresponding Variables
+	var order Order
+	err := json.Unmarshal([]byte(orderJSON), &order)
+	if err != nil {
+		log.Fatal(err)
+	}
+
+	var condition Condition
+	err = json.Unmarshal([]byte(conditionJSON), &condition)
+	if err != nil {
+		log.Fatal(err)
+	}
+
+	fieldName, _ := reflections.GetFieldNameByTagValue(order, "json", condition.Field)
+	fmt.Println(fieldName)
+	fieldValue, _ := reflections.GetField(order, fieldName)
+	fmt.Println(fieldValue)
+
+	// Output:
+	// Step
+	// cooking
+}
diff --git a/reflections.go b/reflections.go
index be2bc02..f39e02e 100644
--- a/reflections.go
+++ b/reflections.go
@@ -101,6 +101,28 @@ func GetFieldTag(obj interface{}, fieldName, tagKey string) (string, error) {
 	return field.Tag.Get(tagKey), nil
 }
 
+// GetFieldNameByTagValue looks up a field with a matching `{tagKey}:"{tagValue}"` tag in the provided `obj` item.
+// The `obj` parameter must be a `struct`, or a `pointer` to one. If the `obj` parameter doesn't have a field tagged
+// with the `tagKey`, and the matching `tagValue`, this function returns an error.
+func GetFieldNameByTagValue(obj interface{}, tagKey, tagValue string) (string, error) {
+	if !isSupportedType(obj, []reflect.Kind{reflect.Struct, reflect.Ptr}) {
+		return "", fmt.Errorf("cannot use GetFieldByTag on a non-struct interface: %w", ErrUnsupportedType)
+	}
+
+	objValue := reflectValue(obj)
+	objType := objValue.Type()
+	fieldsCount := objType.NumField()
+
+	for i := 0; i < fieldsCount; i++ {
+		structField := objType.Field(i)
+		if structField.Tag.Get(tagKey) == tagValue {
+			return structField.Name, nil
+		}
+	}
+
+	return "", errors.New("tag doesn't exist in the given struct")
+}
+
 // SetField sets the provided obj field with provided value.
 //
 // The `obj` parameter must be a pointer to a struct, otherwise it soundly fails.
diff --git a/reflections_test.go b/reflections_test.go
index 4b094d4..c601594 100644
--- a/reflections_test.go
+++ b/reflections_test.go
@@ -513,6 +513,45 @@ func TestItems_deep(t *testing.T) {
 	assert.Equal(t, itemsDeep["Number"], 17)
 }
 
+func TestGetFieldNameByTagValue(t *testing.T) {
+	t.Parallel()
+
+	dummyStruct := TestStruct{
+		Dummy: "dummy",
+		Yummy: 123,
+	}
+
+	tagJSON := "dummytag"
+	field, err := GetFieldNameByTagValue(dummyStruct, "test", tagJSON)
+
+	assert.NoError(t, err)
+	assert.Equal(t, field, "Dummy")
+}
+
+func TestGetFieldNameByTagValue_on_non_existing_tag(t *testing.T) {
+	t.Parallel()
+
+	dummyStruct := TestStruct{
+		Dummy: "dummy",
+		Yummy: 123,
+	}
+
+	// non existing tag value with an existing tag key
+	tagJSON := "tag"
+	_, errTagValue := GetFieldNameByTagValue(dummyStruct, "test", tagJSON)
+	assert.Error(t, errTagValue)
+
+	// non existing tag key with an existing tag value
+	tagJSON = "dummytag"
+	_, errTagKey := GetFieldNameByTagValue(dummyStruct, "json", tagJSON)
+	assert.Error(t, errTagKey)
+
+	// non existing tag key and value
+	tagJSON = "tag"
+	_, errTagKeyValue := GetFieldNameByTagValue(dummyStruct, "json", tagJSON)
+	assert.Error(t, errTagKeyValue)
+}
+
 //nolint:unused
 func TestTags_deep(t *testing.T) {
 	t.Parallel()