diff --git a/custom/conf/app.ini.sample b/custom/conf/app.ini.sample
index 82ffd2d78..a2ac7248e 100644
--- a/custom/conf/app.ini.sample
+++ b/custom/conf/app.ini.sample
@@ -306,6 +306,8 @@ MAX_FILE_SIZE = 1048576
 [admin]
 ; Disallow regular (non-admin) users from creating organizations.
 DISABLE_REGULAR_ORG_CREATION = false
+; Default configuration for email notifications for users (user configurable). Options: enabled, onmention, disabled
+DEFAULT_EMAIL_NOTIFICATIONS = enabled
 
 [security]
 ; Whether the installer is disabled
diff --git a/docs/content/doc/advanced/config-cheat-sheet.en-us.md b/docs/content/doc/advanced/config-cheat-sheet.en-us.md
index 252ceee73..10c6110f3 100644
--- a/docs/content/doc/advanced/config-cheat-sheet.en-us.md
+++ b/docs/content/doc/advanced/config-cheat-sheet.en-us.md
@@ -184,6 +184,9 @@ Values containing `#` or `;` must be quoted using `` ` `` or `"""`.
 - `UPDATE_BUFFER_LEN`: **20**: Buffer length of index request.
 - `MAX_FILE_SIZE`: **1048576**: Maximum size in bytes of files to be indexed.
 
+## Admin (`admin`)
+- `DEFAULT_EMAIL_NOTIFICATIONS`: **enabled**: Default configuration for email notifications for users (user configurable). Options: enabled, onmention, disabled
+
 ## Security (`security`)
 
 - `INSTALL_LOCK`: **false**: Disallow access to the install page.
diff --git a/models/fixtures/user.yml b/models/fixtures/user.yml
index d89dc3c12..37225f144 100644
--- a/models/fixtures/user.yml
+++ b/models/fixtures/user.yml
@@ -6,6 +6,7 @@
   name: user1
   full_name: User One
   email: user1@example.com
+  email_notifications_preference: enabled
   passwd: 7d93daa0d1e6f2305cc8fa496847d61dc7320bb16262f9c55dd753480207234cdd96a93194e408341971742f4701772a025a # password
   type: 0 # individual
   salt: ZogKvWdyEx
@@ -22,6 +23,7 @@
   full_name: "   < U<se>r Tw<o > ><  "
   email: user2@example.com
   keep_email_private: true
+  email_notifications_preference: enabled
   passwd: 7d93daa0d1e6f2305cc8fa496847d61dc7320bb16262f9c55dd753480207234cdd96a93194e408341971742f4701772a025a # password
   type: 0 # individual
   salt: ZogKvWdyEx
@@ -40,6 +42,7 @@
   name: user3
   full_name: " <<<< >> >> > >> > >>> >> "
   email: user3@example.com
+  email_notifications_preference: onmention
   passwd: 7d93daa0d1e6f2305cc8fa496847d61dc7320bb16262f9c55dd753480207234cdd96a93194e408341971742f4701772a025a # password
   type: 1 # organization
   salt: ZogKvWdyEx
@@ -56,6 +59,7 @@
   name: user4
   full_name: "          "
   email: user4@example.com
+  email_notifications_preference: onmention
   passwd: 7d93daa0d1e6f2305cc8fa496847d61dc7320bb16262f9c55dd753480207234cdd96a93194e408341971742f4701772a025a # password
   type: 0 # individual
   salt: ZogKvWdyEx
@@ -72,6 +76,7 @@
   name: user5
   full_name: User Five
   email: user5@example.com
+  email_notifications_preference: enabled
   passwd: 7d93daa0d1e6f2305cc8fa496847d61dc7320bb16262f9c55dd753480207234cdd96a93194e408341971742f4701772a025a # password
   type: 0 # individual
   salt: ZogKvWdyEx
@@ -89,6 +94,7 @@
   name: user6
   full_name: User Six
   email: user6@example.com
+  email_notifications_preference: enabled
   passwd: 7d93daa0d1e6f2305cc8fa496847d61dc7320bb16262f9c55dd753480207234cdd96a93194e408341971742f4701772a025a # password
   type: 1 # organization
   salt: ZogKvWdyEx
@@ -105,6 +111,7 @@
   name: user7
   full_name: User Seven
   email: user7@example.com
+  email_notifications_preference: disabled
   passwd: 7d93daa0d1e6f2305cc8fa496847d61dc7320bb16262f9c55dd753480207234cdd96a93194e408341971742f4701772a025a # password
   type: 1 # organization
   salt: ZogKvWdyEx
@@ -121,6 +128,7 @@
   name: user8
   full_name: User Eight
   email: user8@example.com
+  email_notifications_preference: enabled
   passwd: 7d93daa0d1e6f2305cc8fa496847d61dc7320bb16262f9c55dd753480207234cdd96a93194e408341971742f4701772a025a # password
   type: 0 # individual
   salt: ZogKvWdyEx
@@ -138,6 +146,7 @@
   name: user9
   full_name: User Nine
   email: user9@example.com
+  email_notifications_preference: onmention
   passwd: 7d93daa0d1e6f2305cc8fa496847d61dc7320bb16262f9c55dd753480207234cdd96a93194e408341971742f4701772a025a # password
   type: 0 # individual
   salt: ZogKvWdyEx
diff --git a/models/issue_mail.go b/models/issue_mail.go
index 829c4cea7..87d991e50 100644
--- a/models/issue_mail.go
+++ b/models/issue_mail.go
@@ -70,7 +70,7 @@ func mailIssueCommentToParticipants(e Engine, issue *Issue, doer *User, content
 		if err != nil {
 			return fmt.Errorf("GetUserByID [%d]: %v", watchers[i].UserID, err)
 		}
-		if to.IsOrganization() {
+		if to.IsOrganization() || to.EmailNotifications() != EmailNotificationsEnabled {
 			continue
 		}
 
@@ -78,9 +78,9 @@ func mailIssueCommentToParticipants(e Engine, issue *Issue, doer *User, content
 		names = append(names, to.Name)
 	}
 	for i := range participants {
-		if participants[i].ID == doer.ID {
-			continue
-		} else if com.IsSliceContainsStr(names, participants[i].Name) {
+		if participants[i].ID == doer.ID ||
+			com.IsSliceContainsStr(names, participants[i].Name) ||
+			participants[i].EmailNotifications() != EmailNotificationsEnabled {
 			continue
 		}
 
diff --git a/models/migrations/migrations.go b/models/migrations/migrations.go
index 7d97741a2..15e021c05 100644
--- a/models/migrations/migrations.go
+++ b/models/migrations/migrations.go
@@ -240,6 +240,8 @@ var migrations = []Migration{
 	NewMigration("add index on owner_id of repository and type, review_id of comment", addIndexOnRepositoryAndComment),
 	// v92 -> v93
 	NewMigration("remove orphaned repository index statuses", removeLingeringIndexStatus),
+	// v93 -> v94
+	NewMigration("add email notification enabled preference to user", addEmailNotificationEnabledToUser),
 }
 
 // Migrate database to current version
diff --git a/models/migrations/v93.go b/models/migrations/v93.go
new file mode 100644
index 000000000..0b0441cd5
--- /dev/null
+++ b/models/migrations/v93.go
@@ -0,0 +1,16 @@
+// Copyright 2019 The Gitea Authors. All rights reserved.
+// Use of this source code is governed by a MIT-style
+// license that can be found in the LICENSE file.
+
+package migrations
+
+import "github.com/go-xorm/xorm"
+
+func addEmailNotificationEnabledToUser(x *xorm.Engine) error {
+	// User see models/user.go
+	type User struct {
+		EmailNotificationsPreference string `xorm:"VARCHAR(20) NOT NULL DEFAULT 'enabled'"`
+	}
+
+	return x.Sync2(new(User))
+}
diff --git a/models/user.go b/models/user.go
index ed0fe524e..af4ccacf6 100644
--- a/models/user.go
+++ b/models/user.go
@@ -58,6 +58,13 @@ const (
 	algoScrypt = "scrypt"
 	algoArgon2 = "argon2"
 	algoPbkdf2 = "pbkdf2"
+
+	// EmailNotificationsEnabled indicates that the user would like to receive all email notifications
+	EmailNotificationsEnabled = "enabled"
+	// EmailNotificationsOnMention indicates that the user would like to be notified via email when mentioned.
+	EmailNotificationsOnMention = "onmention"
+	// EmailNotificationsDisabled indicates that the user would not like to be notified via email.
+	EmailNotificationsDisabled = "disabled"
 )
 
 var (
@@ -87,10 +94,11 @@ type User struct {
 	Name      string `xorm:"UNIQUE NOT NULL"`
 	FullName  string
 	// Email is the primary email address (to be used for communication)
-	Email            string `xorm:"NOT NULL"`
-	KeepEmailPrivate bool
-	Passwd           string `xorm:"NOT NULL"`
-	PasswdHashAlgo   string `xorm:"NOT NULL DEFAULT 'pbkdf2'"`
+	Email                        string `xorm:"NOT NULL"`
+	KeepEmailPrivate             bool
+	EmailNotificationsPreference string `xorm:"VARCHAR(20) NOT NULL DEFAULT 'enabled'"`
+	Passwd                       string `xorm:"NOT NULL"`
+	PasswdHashAlgo               string `xorm:"NOT NULL DEFAULT 'pbkdf2'"`
 
 	// MustChangePassword is an attribute that determines if a user
 	// is to change his/her password after registration.
@@ -719,6 +727,21 @@ func (u *User) IsMailable() bool {
 	return u.IsActive
 }
 
+// EmailNotifications returns the User's email notification preference
+func (u *User) EmailNotifications() string {
+	return u.EmailNotificationsPreference
+}
+
+// SetEmailNotifications sets the user's email notification preference
+func (u *User) SetEmailNotifications(set string) error {
+	u.EmailNotificationsPreference = set
+	if err := UpdateUserCols(u, "email_notifications_preference"); err != nil {
+		log.Error("SetEmailNotifications: %v", err)
+		return err
+	}
+	return nil
+}
+
 func isUserExist(e Engine, uid int64, name string) (bool, error) {
 	if len(name) == 0 {
 		return false, nil
@@ -868,6 +891,7 @@ func CreateUser(u *User) (err error) {
 	}
 	u.HashPassword(u.Passwd)
 	u.AllowCreateOrganization = setting.Service.DefaultAllowCreateOrganization && !setting.Admin.DisableRegularOrgCreation
+	u.EmailNotificationsPreference = setting.Admin.DefaultEmailNotification
 	u.MaxRepoCreation = -1
 	u.Theme = setting.UI.DefaultTheme
 
@@ -1253,7 +1277,8 @@ func getUserByName(e Engine, name string) (*User, error) {
 	return u, nil
 }
 
-// GetUserEmailsByNames returns a list of e-mails corresponds to names.
+// GetUserEmailsByNames returns a list of e-mails corresponds to names of users
+// that have their email notifications set to enabled or onmention.
 func GetUserEmailsByNames(names []string) []string {
 	return getUserEmailsByNames(x, names)
 }
@@ -1265,7 +1290,7 @@ func getUserEmailsByNames(e Engine, names []string) []string {
 		if err != nil {
 			continue
 		}
-		if u.IsMailable() {
+		if u.IsMailable() && u.EmailNotifications() != EmailNotificationsDisabled {
 			mails = append(mails, u.Email)
 		}
 	}
diff --git a/models/user_test.go b/models/user_test.go
index 290253c4b..d01b482ae 100644
--- a/models/user_test.go
+++ b/models/user_test.go
@@ -74,6 +74,8 @@ func TestGetUserEmailsByNames(t *testing.T) {
 	// ignore none active user email
 	assert.Equal(t, []string{"user8@example.com"}, GetUserEmailsByNames([]string{"user8", "user9"}))
 	assert.Equal(t, []string{"user8@example.com", "user5@example.com"}, GetUserEmailsByNames([]string{"user8", "user5"}))
+
+	assert.Equal(t, []string{"user8@example.com"}, GetUserEmailsByNames([]string{"user8", "user7"}))
 }
 
 func TestUser_APIFormat(t *testing.T) {
@@ -196,6 +198,37 @@ func TestDeleteUser(t *testing.T) {
 	test(11)
 }
 
+func TestEmailNotificationPreferences(t *testing.T) {
+	assert.NoError(t, PrepareTestDatabase())
+	for _, test := range []struct {
+		expected string
+		userID   int64
+	}{
+		{EmailNotificationsEnabled, 1},
+		{EmailNotificationsEnabled, 2},
+		{EmailNotificationsOnMention, 3},
+		{EmailNotificationsOnMention, 4},
+		{EmailNotificationsEnabled, 5},
+		{EmailNotificationsEnabled, 6},
+		{EmailNotificationsDisabled, 7},
+		{EmailNotificationsEnabled, 8},
+		{EmailNotificationsOnMention, 9},
+	} {
+		user := AssertExistsAndLoadBean(t, &User{ID: test.userID}).(*User)
+		assert.Equal(t, test.expected, user.EmailNotifications())
+
+		// Try all possible settings
+		assert.NoError(t, user.SetEmailNotifications(EmailNotificationsEnabled))
+		assert.Equal(t, EmailNotificationsEnabled, user.EmailNotifications())
+
+		assert.NoError(t, user.SetEmailNotifications(EmailNotificationsOnMention))
+		assert.Equal(t, EmailNotificationsOnMention, user.EmailNotifications())
+
+		assert.NoError(t, user.SetEmailNotifications(EmailNotificationsDisabled))
+		assert.Equal(t, EmailNotificationsDisabled, user.EmailNotifications())
+	}
+}
+
 func TestHashPasswordDeterministic(t *testing.T) {
 	b := make([]byte, 16)
 	rand.Read(b)
diff --git a/modules/setting/setting.go b/modules/setting/setting.go
index 3ff9f89ad..5e476854b 100644
--- a/modules/setting/setting.go
+++ b/modules/setting/setting.go
@@ -231,6 +231,7 @@ var (
 	// Admin settings
 	Admin struct {
 		DisableRegularOrgCreation bool
+		DefaultEmailNotification  string
 	}
 
 	// Picture settings
@@ -754,6 +755,9 @@ func NewContext() {
 		}
 	}
 
+	sec = Cfg.Section("admin")
+	Admin.DefaultEmailNotification = sec.Key("DEFAULT_EMAIL_NOTIFICATIONS").MustString("enabled")
+
 	sec = Cfg.Section("security")
 	InstallLock = sec.Key("INSTALL_LOCK").MustBool(false)
 	SecretKey = sec.Key("SECRET_KEY").MustString("!#@FDEWREWR&*(")
diff --git a/options/locale/locale_en-US.ini b/options/locale/locale_en-US.ini
index d6d54a224..90ee32a25 100644
--- a/options/locale/locale_en-US.ini
+++ b/options/locale/locale_en-US.ini
@@ -557,6 +557,11 @@ confirm_delete_account = Confirm Deletion
 delete_account_title = Delete User Account
 delete_account_desc = Are you sure you want to permanently delete this user account?
 
+email_notifications.enable = Enable Email Notifications
+email_notifications.onmention = Only Email on Mention
+email_notifications.disable = Disable Email Notifications
+email_notifications.submit = Set Email Preference
+
 [repo]
 owner = Owner
 repo_name = Repository Name
@@ -1126,6 +1131,10 @@ settings.basic_settings = Basic Settings
 settings.mirror_settings = Mirror Settings
 settings.sync_mirror = Synchronize Now
 settings.mirror_sync_in_progress = Mirror synchronization is in progress. Check back in a minute.
+settings.email_notifications.enable = Enable Email Notifications
+settings.email_notifications.onmention = Only Email on Mention
+settings.email_notifications.disable = Disable Email Notifications
+settings.email_notifications.submit = Set Email Preference
 settings.site = Website
 settings.update_settings = Update Settings
 settings.advanced_settings = Advanced Settings
diff --git a/public/css/index.css b/public/css/index.css
index ad1d0313f..a60963758 100644
--- a/public/css/index.css
+++ b/public/css/index.css
@@ -786,7 +786,7 @@ footer .ui.left,footer .ui.right{line-height:40px}
 .ui.form .dropzone .dz-error-message{top:140px}
 .settings .content{margin-top:2px}
 .settings .content .segment,.settings .content>.header{box-shadow:0 1px 2px 0 rgba(34,36,38,.15)}
-.settings .list>.item .green{color:#21ba45}
+.settings .list>.item .green:not(.ui.button){color:#21ba45}
 .settings .list>.item:not(:first-child){border-top:1px solid #eaeaea;padding:1rem;margin:15px -1rem -1rem -1rem}
 .settings .list>.item>.mega-octicon{display:table-cell}
 .settings .list>.item>.mega-octicon+.content{display:table-cell;padding:0 0 0 .5em;vertical-align:top}
diff --git a/public/less/_repository.less b/public/less/_repository.less
index ef05beb6f..a66d13891 100644
--- a/public/less/_repository.less
+++ b/public/less/_repository.less
@@ -2013,7 +2013,7 @@
 
     .list {
         > .item {
-            .green {
+            .green:not(.ui.button) {
                 color: #21ba45;
             }
 
diff --git a/routers/user/setting/account.go b/routers/user/setting/account.go
index c6b5c0c2d..674606cce 100644
--- a/routers/user/setting/account.go
+++ b/routers/user/setting/account.go
@@ -6,6 +6,8 @@
 package setting
 
 import (
+	"errors"
+
 	"code.gitea.io/gitea/models"
 	"code.gitea.io/gitea/modules/auth"
 	"code.gitea.io/gitea/modules/base"
@@ -24,6 +26,7 @@ func Account(ctx *context.Context) {
 	ctx.Data["Title"] = ctx.Tr("settings")
 	ctx.Data["PageIsSettingsAccount"] = true
 	ctx.Data["Email"] = ctx.User.Email
+	ctx.Data["EmailNotificationsPreference"] = ctx.User.EmailNotifications()
 
 	loadAccountData(ctx)
 
@@ -82,6 +85,25 @@ func EmailPost(ctx *context.Context, form auth.AddEmailForm) {
 		ctx.Redirect(setting.AppSubURL + "/user/settings/account")
 		return
 	}
+	// Set Email Notification Preference
+	if ctx.Query("_method") == "NOTIFICATION" {
+		preference := ctx.Query("preference")
+		if !(preference == models.EmailNotificationsEnabled ||
+			preference == models.EmailNotificationsOnMention ||
+			preference == models.EmailNotificationsDisabled) {
+			log.Error("Email notifications preference change returned unrecognized option %s: %s", preference, ctx.User.Name)
+			ctx.ServerError("SetEmailPreference", errors.New("option unrecognized"))
+			return
+		}
+		if err := ctx.User.SetEmailNotifications(preference); err != nil {
+			log.Error("Set Email Notifications failed: %v", err)
+			ctx.ServerError("SetEmailNotifications", err)
+			return
+		}
+		log.Trace("Email notifications preference made %s: %s", preference, ctx.User.Name)
+		ctx.Redirect(setting.AppSubURL + "/user/settings/account")
+		return
+	}
 
 	if ctx.HasError() {
 		loadAccountData(ctx)
diff --git a/templates/user/settings/account.tmpl b/templates/user/settings/account.tmpl
index 778103e44..dcb5770ac 100644
--- a/templates/user/settings/account.tmpl
+++ b/templates/user/settings/account.tmpl
@@ -43,7 +43,30 @@
 		<div class="ui attached segment">
 			<div class="ui email list">
 				<div class="item">
-					{{.i18n.Tr "settings.email_desc"}}
+					<form action="{{AppSubUrl}}/user/settings/account/email" class="ui form" method="post">
+						{{.i18n.Tr "settings.email_desc"}}
+						<div class="right floated content">
+							<div class="field">
+								<button class="ui green button">{{$.i18n.Tr "settings.email_notifications.submit"}}</button>
+							</div>
+						</div>
+						<div class="right floated content">
+							{{$.CsrfTokenHtml}}
+							<input name="_method" type="hidden" value="NOTIFICATION">
+							<div class="field">
+								<div class="ui selection dropdown" tabindex="0">
+									<input name="preference" type="hidden" value="{{.EmailNotificationsPreference}}">
+									<i class="dropdown icon"></i>
+									<div class="text">{{$.i18n.Tr "settings.email_notifications"}}</div>
+									<div class="menu">
+										<div data-value="enabled" class="{{if eq .EmailNotificationsPreference "enabled"}}active selected {{end}}item">{{$.i18n.Tr "settings.email_notifications.enable"}}</div>
+										<div data-value="onmention" class="{{if eq .EmailNotificationsPreference "onmention"}}active selected {{end}}item">{{$.i18n.Tr "settings.email_notifications.onmention"}}</div>
+										<div data-value="disabled" class="{{if eq .EmailNotificationsPreference "disabled"}}active selected {{end}}item">{{$.i18n.Tr "settings.email_notifications.disable"}}</div>
+									</div>
+								</div>
+							</div>
+						</div>
+					</form>
 				</div>
 				{{range .Emails}}
 					<div class="item">
@@ -103,7 +126,7 @@
 							<i class="dropdown icon"></i>
 							<div class="text">
 								{{range $i,$a := .AllThemes}}
-								    {{if eq $.SignedUser.Theme $a}}{{$a}}{{end}}
+									{{if eq $.SignedUser.Theme $a}}{{$a}}{{end}}
 								{{end}}
 							</div>