diff --git a/.golangci.example.yml b/.golangci.example.yml
index 32572982..dcd760fc 100644
--- a/.golangci.example.yml
+++ b/.golangci.example.yml
@@ -5,6 +5,10 @@ run:
   tests: true
   build-tags:
     - mytag
+  skip-dirs:
+    - external_libs
+  skip-files:
+    - ".*\\.pb\\.go$"
 
 output:
   format: colored-line-number
diff --git a/README.md b/README.md
index 2bc6a12d..a2324be3 100644
--- a/README.md
+++ b/README.md
@@ -232,6 +232,8 @@ Flags:
       --print-resources-usage       Print avg and max memory usage of golangci-lint and total time
   -c, --config PATH                 Read config from file path PATH
       --no-config                   Don't read config
+      --skip-dirs strings           Regexps of directory names to skip
+      --skip-files strings          Regexps of file names to skip
   -E, --enable strings              Enable specific linter
   -D, --disable strings             Disable specific linter
       --enable-all                  Enable all linters
diff --git a/pkg/commands/run.go b/pkg/commands/run.go
index 97b39374..32c90694 100644
--- a/pkg/commands/run.go
+++ b/pkg/commands/run.go
@@ -71,6 +71,8 @@ func initFlagSet(fs *pflag.FlagSet, cfg *config.Config) {
 	fs.BoolVar(&rc.PrintResourcesUsage, "print-resources-usage", false, wh("Print avg and max memory usage of golangci-lint and total time"))
 	fs.StringVarP(&rc.Config, "config", "c", "", wh("Read config from file path `PATH`"))
 	fs.BoolVar(&rc.NoConfig, "no-config", false, wh("Don't read config"))
+	fs.StringSliceVar(&rc.SkipDirs, "skip-dirs", nil, wh("Regexps of directory names to skip"))
+	fs.StringSliceVar(&rc.SkipFiles, "skip-files", nil, wh("Regexps of file names to skip"))
 
 	// Linters settings config
 	lsc := &cfg.LintersSettings
@@ -194,12 +196,21 @@ func (e *Executor) runAnalysis(ctx context.Context, args []string) (<-chan resul
 	if lintCtx.Program != nil {
 		fset = lintCtx.Program.Fset
 	}
+
+	skipFilesProcessor, err := processors.NewSkipFiles(e.cfg.Run.SkipFiles)
+	if err != nil {
+		return nil, err
+	}
+
 	runner := lint.SimpleRunner{
 		Processors: []processors.Processor{
 			processors.NewPathPrettifier(), // must be before diff processor at least
-			processors.NewExclude(excludeTotalPattern),
 			processors.NewCgo(),
+			skipFilesProcessor,
+
+			processors.NewExclude(excludeTotalPattern),
 			processors.NewNolint(fset),
+
 			processors.NewUniqByLine(),
 			processors.NewDiff(e.cfg.Issues.Diff, e.cfg.Issues.DiffFromRevision, e.cfg.Issues.DiffPatchFilePath),
 			processors.NewMaxPerFileFromLinter(),
diff --git a/pkg/config/config.go b/pkg/config/config.go
index ab172d15..30cff3fb 100644
--- a/pkg/config/config.go
+++ b/pkg/config/config.go
@@ -101,6 +101,9 @@ type Run struct {
 	AnalyzeTests          bool `mapstructure:"tests"`
 	Deadline              time.Duration
 	PrintVersion          bool
+
+	SkipFiles []string `mapstructure:"skip-files"`
+	SkipDirs  []string `mapstructure:"skip-dirs"`
 }
 
 type LintersSettings struct {
diff --git a/pkg/fsutils/fsutils.go b/pkg/fsutils/fsutils.go
index 3de4d7ef..561f9ffd 100644
--- a/pkg/fsutils/fsutils.go
+++ b/pkg/fsutils/fsutils.go
@@ -13,7 +13,12 @@ import (
 	"github.com/sirupsen/logrus"
 )
 
-var stdExcludeDirs = []string{"vendor", "testdata", "examples", "Godeps", "builtin"}
+var stdExcludeDirRegexps = []string{
+	"^vendor$", "^third_party$",
+	"^testdata$", "^examples$",
+	"^Godeps$",
+	"^builtin$",
+}
 
 func GetProjectRoot() string {
 	return path.Join(build.Default.GOPATH, "src", "github.com", "golangci", "golangci-worker")
@@ -101,7 +106,7 @@ func processResolvedPaths(paths *PathResolveResult) (*ProjectPaths, error) {
 	}, nil
 }
 
-func GetPathsForAnalysis(ctx context.Context, inputPaths []string, includeTests bool) (ret *ProjectPaths, err error) {
+func GetPathsForAnalysis(ctx context.Context, inputPaths []string, includeTests bool, skipDirRegexps []string) (ret *ProjectPaths, err error) {
 	defer func(startedAt time.Time) {
 		if ret != nil {
 			logrus.Infof("Found paths for analysis for %s: %s", time.Since(startedAt), ret.MixedPaths())
@@ -114,7 +119,13 @@ func GetPathsForAnalysis(ctx context.Context, inputPaths []string, includeTests
 		}
 	}
 
-	pr := NewPathResolver(stdExcludeDirs, []string{".go"}, includeTests)
+	// TODO: don't analyze skipped files also, when be able to do it
+	excludeDirs := append([]string{}, stdExcludeDirRegexps...)
+	excludeDirs = append(excludeDirs, skipDirRegexps...)
+	pr, err := NewPathResolver(excludeDirs, []string{".go"}, includeTests)
+	if err != nil {
+		return nil, fmt.Errorf("can't make path resolver: %s", err)
+	}
 	paths, err := pr.Resolve(inputPaths...)
 	if err != nil {
 		return nil, fmt.Errorf("can't resolve paths %v: %s", inputPaths, err)
diff --git a/pkg/fsutils/path_resolver.go b/pkg/fsutils/path_resolver.go
index 9bef6633..9c77287d 100644
--- a/pkg/fsutils/path_resolver.go
+++ b/pkg/fsutils/path_resolver.go
@@ -4,12 +4,13 @@ import (
 	"fmt"
 	"os"
 	"path/filepath"
+	"regexp"
 	"sort"
 	"strings"
 )
 
 type PathResolver struct {
-	excludeDirs           map[string]bool
+	excludeDirs           map[string]*regexp.Regexp
 	allowedFileExtensions map[string]bool
 	includeTests          bool
 }
@@ -57,10 +58,15 @@ func (s pathResolveState) toResult() *PathResolveResult {
 	return res
 }
 
-func NewPathResolver(excludeDirs, allowedFileExtensions []string, includeTests bool) *PathResolver {
-	excludeDirsMap := map[string]bool{}
+func NewPathResolver(excludeDirs, allowedFileExtensions []string, includeTests bool) (*PathResolver, error) {
+	excludeDirsMap := map[string]*regexp.Regexp{}
 	for _, dir := range excludeDirs {
-		excludeDirsMap[dir] = true
+		re, err := regexp.Compile(dir)
+		if err != nil {
+			return nil, fmt.Errorf("can't compile regexp %q: %s", dir, err)
+		}
+
+		excludeDirsMap[dir] = re
 	}
 
 	allowedFileExtensionsMap := map[string]bool{}
@@ -72,7 +78,7 @@ func NewPathResolver(excludeDirs, allowedFileExtensions []string, includeTests b
 		excludeDirs:           excludeDirsMap,
 		allowedFileExtensions: allowedFileExtensionsMap,
 		includeTests:          includeTests,
-	}
+	}, nil
 }
 
 func (pr PathResolver) isIgnoredDir(dir string) bool {
@@ -87,7 +93,13 @@ func (pr PathResolver) isIgnoredDir(dir string) bool {
 		return true
 	}
 
-	return pr.excludeDirs[dirName]
+	for _, dirExludeRe := range pr.excludeDirs {
+		if dirExludeRe.MatchString(dirName) {
+			return true
+		}
+	}
+
+	return false
 }
 
 func (pr PathResolver) isAllowedFile(path string) bool {
diff --git a/pkg/fsutils/path_resolver_test.go b/pkg/fsutils/path_resolver_test.go
index bd8e5c22..ae3d383a 100644
--- a/pkg/fsutils/path_resolver_test.go
+++ b/pkg/fsutils/path_resolver_test.go
@@ -53,12 +53,15 @@ func prepareFS(t *testing.T, paths ...string) *fsPreparer {
 	}
 }
 
-func newPR() *PathResolver {
-	return NewPathResolver([]string{}, []string{}, false)
+func newPR(t *testing.T) *PathResolver {
+	pr, err := NewPathResolver([]string{}, []string{}, false)
+	assert.NoError(t, err)
+
+	return pr
 }
 
 func TestPathResolverNoPaths(t *testing.T) {
-	_, err := newPR().Resolve()
+	_, err := newPR(t).Resolve()
 	assert.EqualError(t, err, "no paths are set")
 }
 
@@ -66,7 +69,7 @@ func TestPathResolverNotExistingPath(t *testing.T) {
 	fp := prepareFS(t)
 	defer fp.clean()
 
-	_, err := newPR().Resolve("a")
+	_, err := newPR(t).Resolve("a")
 	assert.EqualError(t, err, "can't find path a: stat a: no such file or directory")
 }
 
@@ -187,6 +190,11 @@ func TestPathResolverCommonCases(t *testing.T) {
 			expDirs:  []string{".", "a/c"},
 			expFiles: []string{"a/c/d.go", "e.go"},
 		},
+		{
+			name:    "vendor dir is excluded by regexp, not the exact match",
+			prepare: []string{"vendors/a.go", "novendor/b.go"},
+			resolve: []string{"./..."},
+		},
 	}
 
 	for _, tc := range testCases {
@@ -194,7 +202,9 @@ func TestPathResolverCommonCases(t *testing.T) {
 			fp := prepareFS(t, tc.prepare...)
 			defer fp.clean()
 
-			pr := NewPathResolver([]string{"vendor"}, []string{".go"}, tc.includeTests)
+			pr, err := NewPathResolver([]string{"vendor"}, []string{".go"}, tc.includeTests)
+			assert.NoError(t, err)
+
 			res, err := pr.Resolve(tc.resolve...)
 			assert.NoError(t, err)
 
diff --git a/pkg/lint/load.go b/pkg/lint/load.go
index 8ca3da13..420f0b44 100644
--- a/pkg/lint/load.go
+++ b/pkg/lint/load.go
@@ -154,7 +154,7 @@ func LoadContext(ctx context.Context, linters []linter.Config, cfg *config.Confi
 		args = []string{"./..."}
 	}
 
-	paths, err := fsutils.GetPathsForAnalysis(ctx, args, cfg.Run.AnalyzeTests)
+	paths, err := fsutils.GetPathsForAnalysis(ctx, args, cfg.Run.AnalyzeTests, cfg.Run.SkipDirs)
 	if err != nil {
 		return nil, err
 	}
diff --git a/pkg/lint/load_test.go b/pkg/lint/load_test.go
index edd721d1..099d028a 100644
--- a/pkg/lint/load_test.go
+++ b/pkg/lint/load_test.go
@@ -19,7 +19,7 @@ func TestASTCacheLoading(t *testing.T) {
 
 	inputPaths := []string{"./...", "./", "./load.go", "load.go"}
 	for _, inputPath := range inputPaths {
-		paths, err := fsutils.GetPathsForAnalysis(ctx, []string{inputPath}, true)
+		paths, err := fsutils.GetPathsForAnalysis(ctx, []string{inputPath}, true, nil)
 		assert.NoError(t, err)
 		assert.NotEmpty(t, paths.Files)
 
diff --git a/pkg/result/processors/skip_files.go b/pkg/result/processors/skip_files.go
new file mode 100644
index 00000000..5b9fa652
--- /dev/null
+++ b/pkg/result/processors/skip_files.go
@@ -0,0 +1,53 @@
+package processors
+
+import (
+	"fmt"
+	"path/filepath"
+	"regexp"
+
+	"github.com/golangci/golangci-lint/pkg/result"
+)
+
+type SkipFiles struct {
+	patterns []*regexp.Regexp
+}
+
+var _ Processor = SkipFiles{}
+
+func NewSkipFiles(patterns []string) (*SkipFiles, error) {
+	var patternsRe []*regexp.Regexp
+	for _, p := range patterns {
+		patternRe, err := regexp.Compile(p)
+		if err != nil {
+			return nil, fmt.Errorf("can't compile regexp %q: %s", p, err)
+		}
+		patternsRe = append(patternsRe, patternRe)
+	}
+
+	return &SkipFiles{
+		patterns: patternsRe,
+	}, nil
+}
+
+func (p SkipFiles) Name() string {
+	return "skip_files"
+}
+
+func (p SkipFiles) Process(issues []result.Issue) ([]result.Issue, error) {
+	if len(p.patterns) == 0 {
+		return issues, nil
+	}
+
+	return filterIssues(issues, func(i *result.Issue) bool {
+		fileName := filepath.Base(i.FilePath())
+		for _, p := range p.patterns {
+			if p.MatchString(fileName) {
+				return false
+			}
+		}
+
+		return true
+	}), nil
+}
+
+func (p SkipFiles) Finish() {}
diff --git a/pkg/result/processors/skip_files_test.go b/pkg/result/processors/skip_files_test.go
new file mode 100644
index 00000000..b416cab9
--- /dev/null
+++ b/pkg/result/processors/skip_files_test.go
@@ -0,0 +1,43 @@
+package processors
+
+import (
+	"go/token"
+	"testing"
+
+	"github.com/golangci/golangci-lint/pkg/result"
+	"github.com/stretchr/testify/assert"
+)
+
+func newFileIssue(file string) result.Issue {
+	return result.Issue{
+		Pos: token.Position{
+			Filename: file,
+		},
+	}
+}
+
+func newTestSkipFiles(t *testing.T, patterns ...string) *SkipFiles {
+	p, err := NewSkipFiles(patterns)
+	assert.NoError(t, err)
+	return p
+}
+
+func TestSkipFiles(t *testing.T) {
+	p := newTestSkipFiles(t)
+	processAssertSame(t, p, newFileIssue("any.go"))
+
+	p = newTestSkipFiles(t, "file")
+	processAssertEmpty(t, p,
+		newFileIssue("file.go"),
+		newFileIssue("file"),
+		newFileIssue("nofile.go"))
+
+	p = newTestSkipFiles(t, ".*")
+	processAssertEmpty(t, p, newFileIssue("any.go"))
+}
+
+func TestSkipFilesInvalidPattern(t *testing.T) {
+	p, err := NewSkipFiles([]string{"\\o"})
+	assert.Error(t, err)
+	assert.Nil(t, p)
+}