added ini-override option
diff --git a/ini.go b/ini.go
index cfdf57c..ed2c755 100644
--- a/ini.go
+++ b/ini.go
@@ -539,6 +539,12 @@
 				continue
 			}
 
+			// ini value is ignored if override is not set or
+			// value was previously set from non default
+			if len(opt.tag.Get("ini-override")) > 0 && !opt.isSetDefault {
+				continue
+			}
+
 			pval := &inival.Value
 
 			if !opt.canArgument() && len(inival.Value) == 0 {
diff --git a/ini_test.go b/ini_test.go
index dd7fe33..492d10f 100644
--- a/ini_test.go
+++ b/ini_test.go
@@ -802,7 +802,7 @@
 	}
 
 	if opts.Values[1] != 222 {
-		t.Fatalf("Expected Values[0] to be 222, but got '%d'", opts.Values[1])
+		t.Fatalf("Expected Values[1] to be 222, but got '%d'", opts.Values[1])
 	}
 }
 
@@ -948,3 +948,57 @@
 		}
 	}
 }
+
+func TestIniOverwriteOptions(t *testing.T) {
+	var tests = []struct {
+		args     []string
+		expected string
+	}{
+		{
+			args:     []string{},
+			expected: "from default",
+		},
+		{
+			args:     []string{"--value", "from CLI"},
+			expected: "from CLI",
+		},
+		{
+			args:     []string{"--config", "no file name"},
+			expected: "from INI",
+		},
+		{
+			args:     []string{"--value", "from CLI before", "--config", "no file name"},
+			expected: "from CLI before",
+		},
+		{
+			args:     []string{"--config", "no file name", "--value", "from CLI after"},
+			expected: "from CLI after",
+		},
+	}
+
+	for _, test := range tests {
+		var opts struct {
+			Config string `long:"config" no-ini:"true"`
+			Value  string `long:"value" default:"from default" ini-override:"true"`
+		}
+
+		p := NewParser(&opts, Default)
+
+		_, err := p.ParseArgs(test.args)
+		if err != nil {
+			t.Fatalf("Unexpected error %s with args %+v", err, test.args)
+		}
+
+		if opts.Config != "" {
+			err = NewIniParser(p).Parse(bytes.NewBufferString("value = from INI"))
+			if err != nil {
+				t.Fatalf("Unexpected error %s with args %+v", err, test.args)
+			}
+		}
+
+		if opts.Value != test.expected {
+			t.Fatalf("Expected Value to be \"%s\" but was \"%s\" with args %+v", test.expected, opts.Value, test.args)
+		}
+
+	}
+}
diff --git a/option.go b/option.go
index 95eaedc..8be7a27 100644
--- a/option.go
+++ b/option.go
@@ -86,10 +86,6 @@
 	defaultLiteral string
 }
 
-func (option *Option) Field() reflect.Value {
-	return option.value
-}
-
 // LongNameWithNamespace returns the option's long name with the group namespaces
 // prepended by walking up the option's group tree. Namespaces and the long name
 // itself are separated by the parser's namespace delimiter. If the long name is
@@ -176,11 +172,6 @@
 	return option.isSet
 }
 
-// IsSetDefault returns true if option has been set with its default value.
-func (option *Option) IsSetDefault() bool {
-	return option.isSetDefault
-}
-
 // Set the value of an option to the specified value. An error will be returned
 // if the specified value could not be converted to the corresponding option
 // value type.
@@ -272,10 +263,10 @@
 
 	if len(usedDefault) > 0 {
 		option.empty()
+		option.isSetDefault = true
 
 		for _, d := range usedDefault {
 			option.set(&d)
-			option.isSetDefault = true
 		}
 	} else {
 		tp := option.value.Type()
diff --git a/parser.go b/parser.go
index f9e07ee..7064553 100644
--- a/parser.go
+++ b/parser.go
@@ -193,6 +193,7 @@
 
 	p.eachOption(func(c *Command, g *Group, option *Option) {
 		option.isSet = false
+		option.isSetDefault = false
 		option.updateDefaultLiteral()
 	})